Firebase is a fantastic place to start: Hosting, Cloud Functions, Firestore, and Auth in one console. The friction shows up later — when you want a relational database, predictable pricing on a real backend, or a container you fully control. This guide walks through migrating a typical Firebase app to PandaStack, component by component, and is honest about the parts that require genuine re-architecture.
What maps to what
| Firebase | PandaStack equivalent | Notes |
|---|---|---|
| Firebase Hosting | Static site | Any framework; auto-detected build |
| Cloud Functions | Edge functions / container app | Depends on use case |
| Firestore (NoSQL) | Managed MongoDB, or PostgreSQL | Data-model decision required |
| Realtime Database | MongoDB / Redis | Depends on access pattern |
| Firebase Auth | Bring your own (e.g. an auth service) | No drop-in replacement |
| Cloud Storage | Object storage / your own bucket | Out of scope here |
The two genuinely hard parts are Firestore → relational and Firebase Auth. Everything else is mostly mechanical. Be honest with yourself about scope before you start.
Step 1: Migrate Hosting (the easy win)
If your Firebase Hosting site is a static SPA, this is the simplest piece. PandaStack auto-detects frameworks (React/Vite, Next export, Astro, Gatsby, Eleventy, VitePoint, Hugo, plain HTML) and runs the build for you.
- 1Connect your Git repo in the PandaStack dashboard.
- 2Confirm the detected build command and output directory (override if needed — install command supports npm/yarn/pnpm/bun).
- 3Deploy. Static builds run in pandastack.ai microVMs.
- 4Point your custom domain; SSL is issued automatically.
If your firebase.json had rewrites for an SPA fallback, replicate that with a single-page-app fallback to index.html.
Step 2: Decide on your database model
This is the decision that shapes the whole migration. Firestore is a document store; PandaStack offers managed MongoDB (closest to Firestore's document model) and managed PostgreSQL/MySQL (relational).
- Lift-and-shift: choose MongoDB. Your document shapes transfer with minimal change. Fastest path.
- Re-architect to relational: choose PostgreSQL. More upfront work modeling tables and relationships, but you gain joins, transactions, constraints, and SQL — often the reason people leave Firestore in the first place.
A pragmatic middle path: lift to MongoDB now to unblock the migration, then move hot collections to PostgreSQL later, one at a time.
Step 3: Export Firestore data
Firestore exports to Cloud Storage in its own format, which isn't directly importable elsewhere. The reliable approach is a script using the Admin SDK to read collections and write portable JSON:
// export-firestore.js
import admin from 'firebase-admin';
import { writeFileSync } from 'fs';
admin.initializeApp({ credential: admin.credential.applicationDefault() });
const db = admin.firestore();
const snap = await db.collection('users').get();
const docs = snap.docs.map(d => ({ id: d.id, ...d.data() }));
writeFileSync('users.json', JSON.stringify(docs, null, 2));
console.log(`Exported ${docs.length} docs`);Watch out for Firestore-specific types: Timestamp, GeoPoint, DocumentReference. Convert timestamps to ISO 8601 strings and references to plain IDs during export.
Step 4: Import into your managed database
Provision the database in PandaStack. When you attach it to your app, the connection string is injected automatically as DATABASE_URL — no copying secrets between dashboards.
For MongoDB:
mongoimport --uri "$DATABASE_URL" --collection users --file users.json --jsonArrayFor PostgreSQL, write a small loader that maps each JSON document to a row, flattening nested fields into columns or jsonb as appropriate:
CREATE TABLE users (
id TEXT PRIMARY KEY,
email TEXT,
created_at TIMESTAMPTZ,
profile JSONB
);jsonb is a useful escape hatch for irregular nested data while you incrementally normalize.
Step 5: Migrate Cloud Functions
Triage your functions into two buckets:
- Short, stateless, event-ish (webhook handlers, lightweight transforms): port to edge functions (Node.js, Python, Go runtimes).
- Long-running, stateful, or framework-heavy (an Express API, background processing): fold into a container app. Often it's cleaner to consolidate a dozen HTTP-triggered functions into one container running your existing framework.
The big behavioral change: Firebase Functions auto-injected Firebase Admin and Firestore access. After migration you connect to your database via DATABASE_URL like any normal app. That's more explicit — and more portable.
Step 6: Replace Firebase Auth (the honest part)
There is no drop-in replacement for Firebase Auth, and pretending otherwise wastes your time. Options:
- Run an open-source auth server as a container app.
- Use a third-party auth provider via integration.
- Build minimal JWT auth if your needs are simple.
If you have existing users, plan a password-reset-on-first-login flow — you generally cannot export Firebase password hashes in a directly reusable form for arbitrary systems. Migrate user records (email, profile, roles); force a credential reset for the secret material.
Step 7: Cutover
- 1Deploy the full stack (static + container/functions + DB) on PandaStack and test against a staging domain.
- 2Do a final delta export/import for data written since your first import (or run dual-write briefly).
- 3Switch DNS to PandaStack. SSL auto-provisions.
- 4Keep Firebase running read-only for a rollback window before tearing it down.
Migration checklist
- [ ] Hosting → static site deployed and domain tested
- [ ] Database model chosen (MongoDB vs PostgreSQL)
- [ ] Data exported with type conversions handled
- [ ] Data imported; row/doc counts verified
- [ ] Functions triaged and ported
- [ ] Auth replacement chosen and tested
- [ ] Delta sync + DNS cutover plan written
- [ ] Firebase kept as rollback for a window
References
- [Firebase Admin SDK](https://firebase.google.com/docs/admin/setup)
- [Firestore data export/import](https://firebase.google.com/docs/firestore/manage-data/export-import)
- [MongoDB
mongoimport](https://www.mongodb.com/docs/database-tools/mongoimport/) - [PostgreSQL
jsonbtype](https://www.postgresql.org/docs/current/datatype-json.html) - [Twelve-Factor App: backing services](https://12factor.net/backing-services)
---
The nicest part of landing on PandaStack: connect your repo, and your managed database is auto-wired with DATABASE_URL injected — no glue code. The free tier (1 database, 5 web services, edge functions included) is enough to run the whole migration as a dry run. Start at [dashboard.pandastack.io](https://dashboard.pandastack.io).