How to Migrate from Firebase to Appwrite
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
| Firebase | Appwrite | Effort |
|---|---|---|
| Firestore | Appwrite Databases | 🟡 Medium — document-based, easier than SQL migration |
| Firebase Auth | Appwrite Auth | 🟢 Low — similar API |
| Cloud Storage | Appwrite Storage | 🟢 Low — file migration |
| Cloud Functions | Appwrite Functions | 🟡 Medium — rewrite to Appwrite SDK |
| Realtime Database | Appwrite Realtime | 🟢 Low — subscription-based |
| Firebase Hosting | Not included | Use 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.