Supabase or Firebase, and why I ended up picking neither
The comparison everyone writes is Postgres versus documents. The question that actually decided it for me was what happens the day I want to leave.
I looked hard at both of these while deciding what to build my agency's software on, and ended up using neither. The reasoning is more useful than the verdict, so here is the whole thing.
The difference that gets written about
Firebase gives you Firestore, a document database. Supabase gives you Postgres, a relational one. Both wrap it in authentication, file storage, serverless functions and a client library, so from a distance they look like the same product.
The data model is a real difference and it decides more than people expect. Documents are pleasant when your data is genuinely tree shaped and each screen reads one branch of it. They get painful the moment you want to ask a question across the whole dataset, because the queries you can run were determined by how you chose to nest things months earlier. Relational schemas make you decide structure up front and then let you ask questions you had not thought of.
My rule: if you can imagine wanting a report that spans several entities, and you almost always can once a business is real, you want SQL. Every document database I have watched a team adopt eventually grew a second system alongside it to answer reporting questions.
The difference that decided it
What happens when you want out.
Supabase is Postgres. Not Postgres-like, not Postgres-compatible. If you leave, you take a database dump and restore it somewhere else, because that is a solved problem with thirty years of tooling behind it. The platform is open source and you can run it yourself.
Firestore is proprietary and there is no equivalent elsewhere. Leaving means an export, a translation layer, and rewriting every query in your application, because the query semantics do not exist outside Google. That is not a criticism of how well it works. It is a description of the cost of changing your mind, and that cost is worth pricing on day one, when it is theoretical, rather than in year three when it is not.
Pricing, honestly
Firebase bills per operation. Every document read, write and delete. This is fine at small scale and it is the thing that generates the horror stories, because a loop that reads a collection on every render is a bug in Firebase and a bill in Firebase. The cost is proportional to how carefully your code was written, which is an uncomfortable property.
Supabase bills more like a hosted database, closer to compute and storage. Easier to predict, less forgiving if your usage is tiny, because you are paying for a thing that is running rather than for what you did with it.
Where each one wins
Firebase, if you are shipping a mobile app fast, your data is genuinely per-user and tree shaped, you want offline sync that already works, and you are inside Google's ecosystem anyway. The offline story is still better than the alternatives and it is not close.
Supabase, if your data is relational, you want SQL, you care about being able to leave, or you might eventually need to self-host for a client who insists the data sits somewhere specific.
Why I used neither
Because my constraint was different from the one both products optimise for.
I built on Cloudflare Workers with D1 and KV. The deciding factor was that my software serves a team spread across five countries and a set of clients spread wider, and what I wanted was for the thing to be fast for all of them without me operating regional infrastructure. Workers run at the edge by default. That is the whole reason.
It came with real costs and I would rather state them than pretend it was free. There is a CPU time limit per request that has genuinely shaped how I write things. D1 is SQLite, so several things I would expect in Postgres are absent and I have worked around each one. The ecosystem is smaller and some problems have no blog post about them.
The honest summary is that I traded developer convenience for latency and running cost, deliberately, because latency and running cost were my problem. If your problem is shipping something quickly with a small team, that trade is a bad one and Supabase is where I would start.
Which is the actual lesson. These comparisons get written as though one product is better, and the useful question is which constraint you are optimising against. Name that first and the answer usually stops being a debate.