Skip to main content

How to Migrate from Firebase to Appwrite

·OSSAlt Team
firebaseappwritemigrationbackendguide

How to Migrate from Firebase to Appwrite

Appwrite is a self-hosted Firebase alternative with a similar developer experience — databases, auth, storage, functions, and real-time, all in one Docker deployment. Here's how to migrate.

What Maps

FirebaseAppwriteEffort
FirestoreAppwrite Databases🟡 Medium — document-based, easier than SQL migration
Firebase AuthAppwrite Auth🟢 Low — similar API
Cloud StorageAppwrite Storage🟢 Low — file migration
Cloud FunctionsAppwrite Functions🟡 Medium — rewrite to Appwrite SDK
Realtime DatabaseAppwrite Realtime🟢 Low — subscription-based
Firebase HostingNot includedUse Vercel/Netlify

Key advantage: Appwrite uses a document-based database, so the Firestore migration is easier than going to PostgreSQL.

Step 1: Deploy Appwrite

docker run -it --rm \
  --volume /var/run/docker.sock:/var/run/docker.sock \
  --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
  --entrypoint="install" \
  appwrite/appwrite:latest

Or with Docker Compose for production:

docker compose up -d

Access the console at localhost:80 and create your project.

Step 2: Migrate Database

Appwrite uses a document database — collections with documents, similar to Firestore.

Export Firestore:

const admin = require('firebase-admin');
admin.initializeApp();

async function exportCollection(name) {
  const snapshot = await admin.firestore().collection(name).get();
  return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
}

Create Appwrite collections and import:

const { Client, Databases, ID } = require('node-appwrite');

const client = new Client()
  .setEndpoint('https://your-appwrite.com/v1')
  .setProject('your-project')
  .setKey('your-api-key');

const databases = new Databases(client);

// Create collection
await databases.createCollection('main-db', 'posts', 'Posts');

// Create attributes
await databases.createStringAttribute('main-db', 'posts', 'title', 255, true);
await databases.createStringAttribute('main-db', 'posts', 'content', 10000, false);

// Import documents
for (const post of firestorePosts) {
  await databases.createDocument('main-db', 'posts', ID.unique(), {
    title: post.title,
    content: post.content,
  });
}

Step 3: Migrate Auth

const { Users } = require('node-appwrite');
const users = new Users(client);

// Import users from Firebase export
for (const user of firebaseUsers) {
  await users.create(
    ID.unique(),
    user.email,
    undefined, // phone
    undefined, // password (users will reset)
    user.displayName
  );
}

Step 4: Migrate Storage

const { Storage } = require('node-appwrite');
const storage = new Storage(client);

// Create bucket
await storage.createBucket('uploads', 'Uploads');

// Upload files
for (const file of firebaseFiles) {
  const content = await downloadFromFirebase(file.path);
  await storage.createFile('uploads', ID.unique(), content);
}

Step 5: Update Client Code

Before (Firebase):

import { getFirestore, collection, getDocs } from 'firebase/firestore';
const db = getFirestore();
const snapshot = await getDocs(collection(db, 'posts'));

After (Appwrite):

import { Client, Databases } from 'appwrite';
const client = new Client()
  .setEndpoint('https://your-appwrite.com/v1')
  .setProject('your-project');
const databases = new Databases(client);
const response = await databases.listDocuments('main-db', 'posts');

Step 6: Set Up Realtime

// Appwrite realtime subscriptions
import { Client } from 'appwrite';
const client = new Client().setEndpoint('...').setProject('...');

client.subscribe('databases.main-db.collections.posts.documents', (response) => {
  console.log('Document changed:', response.payload);
});

The Bottom Line

Appwrite's document-based database makes Firebase migration easier than going to a relational database like Supabase. The API patterns are similar, and the self-hosted deployment gives you full control. Plan for 1-2 weeks for a medium-sized app.


Compare BaaS platforms on OSSAlt — database models, auth options, and deployment side by side.