Builders

    How to Migrate from Firebase to Supabase

    A Firebase project migrating to Supabase: Firestore documents becoming Postgres tables, Auth users ported, and Firebase Rules rewritten as Row Level Security.

    Migrating from Firebase to Supabase means moving four things rather than one: your Firestore data into Postgres tables, your Firebase Auth users into Supabase Auth, your storage files, and, most importantly for security, your access rules from Firebase Security Rules to Supabase Row Level Security. Supabase provides an open-source migration toolset and official guides that handle the data and user parts, and you can bring users across with their existing passwords rather than forcing a reset. The step you cannot skip is re-implementing your access control as Row Level Security and enabling it on every table before you import data, because an unsecured Postgres table is public in a way a Firestore collection governed by rules is not.

    Short answer

    The migration has four parts, and one of them is a security rewrite you must not overlook. Per Supabase's Firestore migration guide, you export your Firestore documents and load them into relational Postgres tables, flattening or splitting nested data. Per Supabase's Auth migration guide, tools export your Firebase Auth users and import them into Supabase's auth.users, and you can preserve passwords using Firebase's password hash parameters or a first-login middleware. The critical difference is access control: Firebase Security Rules become Supabase Row Level Security policies, which you must enable on every table before importing, or the data is public.

    What migrating actually involves

    A Firebase-to-Supabase migration is really four migrations plus a code change, and treating it as a single copy is where people go wrong. You move Firestore data from a NoSQL document store into a relational Postgres database, you port your Firebase Auth users into Supabase Auth, you move files from Firebase Storage into Supabase Storage, and you re-implement your Firebase Security Rules as Row Level Security policies. Then you update your app to call the Supabase client instead of the Firebase SDK.

    The reason to see it as separate pieces is that they have different tools and different risks. The data and user moves are largely mechanical with Supabase's tooling, the storage move is a file copy, but the security rewrite is a genuine reimplementation because the two platforms enforce access completely differently. So plan the migration as these distinct tracks, and give the security rewrite the most attention, since it is the part that a tool cannot do for you and the part where a mistake exposes data.

    Migrate your Firestore data to Postgres

    The data migration is a model change, not just a copy, because Firestore is schemaless documents and Postgres is relational tables. You export your Firestore collections and load them into tables, and along the way you design a schema: deciding which fields become columns, how to handle nested objects, and what to do with subcollections. Supabase's tooling lets you customize the export, and a common step is to flatten nested JSON or split it into separate, related tables, though you can also keep flexible data in a jsonb column.

    So the work here is thinking through your data model rather than running one command. Denormalized Firestore documents often map to several related tables with foreign keys, and choosing that structure well is what lets you use Postgres features like joins and constraints afterward. Take the migration as an opportunity to define a real schema, since carrying a document blob straight into a single table works but gives up much of what you moved to Postgres for. Once the schema is set, the export tool populates the tables.

    Port your Firebase Auth users

    You can bring your Firebase Auth users into Supabase Auth without forcing everyone to reset their password, which is usually the biggest worry. Supabase provides tools to export users from Firebase to a JSON file and import them into the auth.users table of your Supabase Postgres instance. To preserve passwords, you retrieve your Firebase project's password hash parameters, the signer key, salt separator, rounds, and memory cost from the Firebase Console, so Supabase can validate the existing hashes, since Firebase uses a scrypt-based scheme.

    There is an alternative for a smoother experience, which the migration tooling documents. You can run a middleware component that, the first time each user logs in, verifies their existing Firebase password and then updates it in Supabase, migrating users gradually as they sign in. Either way, the goal is that users keep their credentials, so choose the bulk hash-parameter import if you want everyone moved at once, or the first-login middleware if you prefer a gradual, transparent migration. What you avoid in both cases is a mass password reset.

    What migration tools does Supabase provide?

    Supabase maintains an open-source firebase-to-supabase toolset alongside its official migration guides, so you are not building the migration from scratch. For users, the tools export your Firebase Auth accounts to a JSON file and then import them into Supabase, inserting them into the auth.users table. For data, the tooling exports Firestore collections and lets you shape the output with a custom hook to flatten or restructure nested documents into tables. There is also guidance for moving files from Firebase Storage to Supabase Storage.

    So the practical toolkit covers the mechanical parts of the migration: users, data, and storage each have a supported path. What the tools deliberately do not do is design your schema or write your security policies, because those are decisions specific to your app. So use the Supabase tooling for the heavy lifting of moving records and files, and reserve your own effort for the schema design and the Row Level Security rewrite, which are the parts that shape whether the result is correct and safe.

    Rewrite security: Firebase Rules become Row Level Security

    This is the part that most affects safety and cannot be copied over: Firebase Security Rules and Supabase Row Level Security are different mechanisms, so you reimplement your access control rather than migrate it. Firebase Rules are declarative rules attached to your database that gate reads and writes per path. Supabase enforces access with Row Level Security policies written in SQL on your Postgres tables, defining what each role can select, insert, update, and delete, commonly keyed on the authenticated user with a pattern like auth.uid() equals the row's user id.

    The danger during migration is the default. A Postgres table without Row Level Security enabled is fully readable and writable by anyone with your public API key, which is the opposite of a Firestore collection that a rule was protecting. So you must enable Row Level Security on every table and write policies before you import data and expose the tables, not after. Doing it in the wrong order, or forgetting a table, is exactly how migrated apps end up with public data, so treat enabling and testing RLS as a required step of the migration rather than a follow-up.

    Firebase Rules versus Supabase RLS at a glance

    The two enforce access differently, which the table below summarizes so you can translate your rules.

    AspectFirebase Security RulesSupabase Row Level Security
    Where it livesRules attached to the databaseSQL policies on each table
    Default without itDenies by default in locked modeTable is public until RLS is enabled
    Unit of controlDocument paths and collectionsRows in a table, per operation
    Identity checkrequest.authauth.uid() in a policy
    How you write itRules languageSQL policies

    Read the second row as the migration trap: you must actively enable Row Level Security on Postgres tables, because unlike locked Firestore, an unprotected table is open.

    Rewrite your client code

    The final piece is your application code, since it currently speaks the Firebase SDK and must call the Supabase client instead. Data access changes from Firestore document and collection reads to Supabase queries against Postgres, which are relational and go through Supabase's API. Authentication calls change from Firebase Auth methods to Supabase Auth, and file access moves to the Supabase Storage client.

    This is mechanical but broad, because it touches everywhere your app reads or writes data or handles sign-in. So plan to work through your data and auth calls systematically, testing each against the new backend, ideally after the schema and RLS policies are in place so you are validating against the real access rules. Doing the code change last, once data, users, and security are set up in Supabase, lets you point the app at a backend that is already correct rather than debugging the move and the rules at the same time.

    Migration checklist

    Working through these steps migrates cleanly and safely. The checklist below covers them.

    StepActionDone?
    Design the schemaMap Firestore documents to Postgres tables[ ]
    Enable and write RLSTurn on Row Level Security before importing[ ]
    Migrate the dataExport Firestore and load the tables[ ]
    Port the usersImport Auth users, preserving passwords[ ]
    Move storageCopy files to Supabase Storage[ ]
    Rewrite the clientSwap the Firebase SDK for the Supabase client[ ]

    The step teams skip most is enabling Row Level Security before importing, since a Postgres table left without it is public, which is the leading way a migrated app leaks data.

    Where a scan fits

    A migration changes your whole security model, so once you are on Supabase it is worth verifying that the new setup is actually locked down rather than assuming the move preserved your protection.

    A scanner like PTKD.com analyzes your app build and flags issues such as an exposed service key, over-broad permissions, and client-trusted access that should be enforced server-side, mapped to OWASP MASVS. To be clear about the boundary: PTKD does not run your migration or write your Row Level Security policies, which are your Supabase setup. It helps you confirm, after the move, that you are not shipping a secret in the app and that access is enforced, which is exactly where a Firebase-to-Supabase migration most often goes wrong.

    What to take away

    • Migrating from Firebase to Supabase means moving data, auth users, storage, and access rules, then rewriting your client code, not a single copy.
    • Firestore documents become Postgres tables, so design a schema and flatten or split nested data rather than dumping a document blob into one column.
    • You can port Firebase Auth users with their passwords using Firebase's hash parameters or a first-login middleware, avoiding a mass reset.
    • Supabase provides an open-source firebase-to-supabase toolset and guides for the data, user, and storage moves, but not for your schema or security.
    • Firebase Rules become Supabase Row Level Security, which you must enable on every table before importing or the data is public, and a tool like PTKD.com helps confirm the new setup is locked down.
    • #firebase
    • #supabase
    • #migration
    • #row level security
    • #supabase auth

    Frequently asked questions

    What does migrating from Firebase to Supabase involve?
    Four moves plus a code change. You migrate Firestore data into relational Postgres tables, port your Firebase Auth users into Supabase Auth, move files from Firebase Storage into Supabase Storage, and reimplement your Firebase Security Rules as Supabase Row Level Security policies, then update your app to call the Supabase client instead of the Firebase SDK. The data and user moves are largely mechanical with Supabase's tooling, but the security rewrite is a genuine reimplementation because the two platforms enforce access completely differently, so it needs the most care.
    What tools does Supabase provide for the migration?
    Supabase maintains an open-source firebase-to-supabase toolset alongside official migration guides. For users, the tools export your Firebase Auth accounts to a JSON file and import them into Supabase's auth.users table. For data, the tooling exports Firestore collections and lets you shape the output with a custom hook to flatten or restructure nested documents into tables, and there is guidance for moving Firebase Storage files to Supabase Storage. What the tools do not do is design your schema or write your Row Level Security policies, which are decisions specific to your app.
    Can I migrate Firebase Auth users without resetting passwords?
    Yes. Supabase's tools export your Firebase Auth users and import them into the auth.users table, and to preserve passwords you retrieve your Firebase project's password hash parameters, the signer key, salt separator, rounds, and memory cost, from the Firebase Console, so Supabase can validate the existing scrypt hashes. Alternatively, you can run a middleware that verifies each user's existing Firebase password the first time they log in and then updates it in Supabase, migrating users gradually as they sign in. Either way you avoid a mass password reset.
    How do Firebase Security Rules translate to Supabase?
    They do not translate directly; you reimplement them. Firebase Security Rules are declarative rules attached to the database that gate reads and writes per document path, while Supabase enforces access with Row Level Security policies written in SQL on each Postgres table, defining what a role can select, insert, update, and delete, commonly keyed on the authenticated user with a pattern like auth.uid() equals the row's user id. So you rewrite your access logic as SQL policies rather than porting the rules file, table by table, matching the behavior your Firebase rules provided.
    What is the biggest security risk when migrating to Supabase?
    Forgetting to enable Row Level Security. A Postgres table without RLS enabled is fully readable and writable by anyone with your public API key, which is the opposite of a Firestore collection protected by a rule. So you must enable Row Level Security on every table and write policies before you import data and expose the tables, not after. Doing it in the wrong order, or missing a table, is exactly how migrated apps end up with public data, so treat enabling and testing RLS as a required migration step rather than a follow-up.
    Do I need to rewrite my app code to migrate?
    Yes. Your app currently uses the Firebase SDK and must call the Supabase client instead. Data access changes from Firestore document and collection reads to Supabase queries against Postgres, authentication calls change from Firebase Auth to Supabase Auth, and file access moves to the Supabase Storage client. It is mechanical but broad, touching everywhere your app reads, writes, or handles sign-in. Do this last, once the schema, data, users, and Row Level Security are in place, so you point the app at a backend that is already correct.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free