Docs

Tutorial: move a Firebase app to Sovaria

A step-by-step move of a Firebase app: export Auth with its password hashes, import Firestore and Storage, turn security rules into policies, keep your Firestore code with an import change, and move Cloud Functions.

Updated Oct 24, 2026

This walks through a whole move, from exporting users to switching traffic. The importer's details are in Migrate from Supabase or Firebase; this page is the order to do it in, and how to check each step.

#1. Prepare

  • Create the Sovaria project, install the CLI and sign in: npm install -g @sovaria/cli, sov login, sov scope pick.
  • Create a Firebase service account with read access to Firestore and Storage, and download its JSON (sa.json).
  • Copy the password hash parameters: Firebase console › Authentication › Users › ⋮ › Password hash parameters, saved as hash.json.
  • Copy your firestore.rules file.
firebase auth:export users.json --format=json --project YOUR_PROJECT

#2. Dry run, then import

sov import firebase --service-account sa.json \
  --auth-export users.json --hash-config hash.json --rules firestore.rules --dry-run

sov import firebase --service-account sa.json \
  --auth-export users.json --hash-config hash.json --rules firestore.rules
  • Auth goes first, so the importer can write sovaria-import-uid-map.json (old Firebase uid → new Sovaria user id) and replace old uids inside your documents, ids and paths. users/{uid} is still each user's own document. Turn that off with --keep-uids only if your app stores uids somewhere the importer can't see.
  • Every collection and subcollection keeps its path. Document ids with characters Sovaria doesn't allow are cleaned and listed in the report.
  • Passwords keep working: Firebase's scrypt hash is checked on each user's first sign-in, then upgraded. Nobody has to reset.

#3. Turn security rules into policies

sovaria-rules-report.md lists every rule with its Sovaria equivalent: public, signed-in users, owner only, or a custom policy. Nothing is applied automatically. Add the policies under Policies (or with sov policy upsert), then prove them with a simulation.

match /users/{uid}/orders/{orderId} {
  allow read, write: if request.auth != null && request.auth.uid == uid;
}

#4. Check that everything arrived

  • Compare document counts for your main collections: getCountFromServer on both sides, or the Collections page.
  • Sign in as a test user with their old password through the SDK (await sov.auth.signIn(email, oldPassword)).
  • Open a few documents you know well and check nested maps, arrays and timestamps. Times are stored as ISO-8601 strings (Firebase-style code (Firestore API)).
  • Compare Storage file counts per folder.

#5. Switch the app

import { initializeApp } from 'firebase/app'
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth'
import { getFirestore, collection, query, where, onSnapshot } from 'firebase/firestore'

const app = initializeApp(firebaseConfig)
await signInWithEmailAndPassword(getAuth(app), email, password)
const db = getFirestore(app)
  • Firestore code keeps working with the import change (Firebase-style code (Firestore API)). Auth and Storage calls move to the Sovaria SDK.
  • Flutter, iOS and Android apps use the native SDKs (Mobile apps). Their collection APIs follow Firestore's, but the calls change, so plan time for it.
  • Offline persistence works the Firebase way on the web (Offline-first apps).

#6. Move Cloud Functions

FirebaseSovaria
onDocumentCreated('orders/{id}', …)A trigger on db.document, resource orders, event document.created (Event triggers).
onCall / onRequestA function called with sovaria.functions.call or over POST /functions/v1/<name> (Functions).
onScheduleA function schedule (Event triggers).
beforeUserCreated / beforeUserSignedInBlocking auth hooks (Blocking hooks (before create, before sign-in)).
onObjectFinalizedA trigger on storage.object, event object.created.
Firebase Admin SDK in functionsYour project API with a server key from the function's secrets (Deploying and running functions).

#7. Cut over

  • The import is a snapshot. Plan a short write freeze, re-import the data into a fresh project, check counts, then release the app version that points at Sovaria.
  • Users signed in to the old app have to sign in once more. Their passwords still work.
  • Keep the Firebase project read-only for a week or two before you delete it.

#Coming from Firebase or Supabase?

PlatformWhat this is called there
FirebaseFirebase migration
SovariaTutorial: move a Firebase app to Sovaria

Moving an existing app? Migrate from Supabase or Firebase imports users (with their passwords), data, files and rules.