ichibaseichibase

Migrate from Firebase

Bring a Firebase app into ichibase: Firestore documents and Firebase Authusers. Firestore can land in MongoDB (1:1) or Postgres (typed tables inferred from your documents). Users keep their existing passwords — verified against Firebase's scrypt on first login, then upgraded to Argon2id.

1 · Get a service-account key

In the Firebase console open Project settings → Service accounts → Generate new private key. Save the JSON file — the CLI reads Firestore with it, on your machine. It is never uploaded.

2 · Export your Auth users

Firestore data and Auth users live in different places, so Auth is exported separately with the Firebase CLI:

firebase auth:export users.json --format=json --project <your-project>

Password hashes in that file are Firebase's scryptvariant, which needs your project's hash parameters. Find them in Authentication → (⋮ menu) → Password hash parameters:

ParameterFlagNotes
signer key--auth-fb-signer-keybase64 string
salt separator--auth-fb-salt-separatorbase64 string
rounds--auth-fb-roundssmall integer (often 8)
mem cost--auth-fb-mem-costsmall integer (often 14)

3 · Extract the bundle

Pick where Firestore should land with --target: mongo imports collections 1:1; postgres scans every document and builds typed tables (see below). Pass the auth export and hash parameters to migrate passwords:

ichibase migrate firebase \
  --service-account ./service-account.json \
  --target mongo \
  --auth-export ./users.json \
  --auth-fb-signer-key "<signerKey-base64>" \
  --auth-fb-salt-separator "<saltSeparator-base64>" \
  --auth-fb-rounds 8 \
  --auth-fb-mem-cost 14 \
  --out ./bundle

Then push it (or drop the bundle folder into Database → Import / Migrate in the dashboard):

ichibase migrate push --project <slug> --bundle ./bundle --token "$ICHIBASE_TOKEN"

What gets migrated

  • Firestore documents — each top-level collection becomes a collection (Mongo) or table (Postgres). Subcollections are flattened into separate parent__child collections/tables with a _parent_id reference back to the owning document.
  • Auth users — email, verified flag, created date, and federated identities (Google / Apple / GitHub / … become OAuth links). The Firebase UID is kept in user metadata.
  • Passwords— verified seamlessly on first login against Firebase's scrypt, then upgraded to Argon2id. No reset needed. OAuth-only users sign in with their provider.

Firestore type mapping

Firestore type→ MongoDB (1:1)→ Postgres (inferred)
string / number / boolsametext / bigint·double precision / boolean
timestampdatetimestamptz
map (nested object)embedded objectjsonb
arrayarrayjsonb
GeoPoint{lat, lng}jsonb
referencepath stringtext
bytesbinaryjsonb

Firestore → Postgres (auto-schema)

With --target postgres there's no fixed schema to copy, so the CLI scans every document in a collection and infers a column per field: all-integer → bigint, mixed numbers → double precision, booleans → boolean, timestamps → timestamptz, strings → text. Nested objects and arrays become jsonb; a field whose type is inconsistent across documents falls back to text. The document id becomes the id primary key. This is best-effort — review the inferred tables in the dashboard after import, and see the inference rules & gotchas.

Accounts stored in Firestore (instead of Auth)

Some apps keep profiles/accounts as a Firestore collection rather than in Firebase Auth. In that case skip the auth export and point the bring-your-own-users flags at that collection — e.g. --auth-collection users --auth-email-field email. The two paths are mutually exclusive: use the Firebase Auth export or a Firestore users collection, not both.

Troubleshooting

SymptomFix
Password logins fail after migratingHash params are wrong. They can’t be validated ahead of time (no plaintext to test). Re-check signer key / salt separator / rounds / mem cost and re-import auth.
Federated “Sign in with Google” doesn’t resolveConfigure the matching OAuth provider in your project — the link is imported, the provider config isn’t.
Export is slow / large Google Cloud read billReading every document counts as Firestore reads; --target postgres scans everything to infer the schema. Expect time + cost on big projects.
A subcollection looks missingIt’s flattened to parent__child with a _parent_id column — look for that table/collection.
Your hash parameters must be correct or password logins will fail — OAuth users are unaffected. After import, marking everyone verified is one click via Auth → Users → Verify all if you trust the source.