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:
| Parameter | Flag | Notes |
|---|---|---|
| signer key | --auth-fb-signer-key | base64 string |
| salt separator | --auth-fb-salt-separator | base64 string |
| rounds | --auth-fb-rounds | small integer (often 8) |
| mem cost | --auth-fb-mem-cost | small 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 ./bundleThen 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__childcollections/tables with a_parent_idreference 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 / bool | same | text / bigint·double precision / boolean |
| timestamp | date | timestamptz |
| map (nested object) | embedded object | jsonb |
| array | array | jsonb |
| GeoPoint | {lat, lng} | jsonb |
| reference | path string | text |
| bytes | binary | jsonb |
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
| Symptom | Fix |
|---|---|
| Password logins fail after migrating | Hash 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 resolve | Configure the matching OAuth provider in your project — the link is imported, the provider config isn’t. |
| Export is slow / large Google Cloud read bill | Reading every document counts as Firestore reads; --target postgres scans everything to infer the schema. Expect time + cost on big projects. |
| A subcollection looks missing | It’s flattened to parent__child with a _parent_id column — look for that table/collection. |
