
Firestore is a product decision, not a database religion.
We use Firestore on purpose: live status, offline agents, the picture three roles have to share right now. We also know the week we will walk away from it. This is that line.


People ask "why not Postgres?" the way some people ask why you did not buy the other phone. There is a correct answer in the abstract. There is also the product in front of you.
A lot of our work is not a warehouse. It is a shared picture. An agent updates a booth. A supervisor needs to see it before they walk over. A user on the other side of the grounds should not be working off a message from twenty minutes ago. That problem has a shape. Firestore fits that shape. Postgres can be forced into it. I have done both. I know which week I enjoyed.
What we are actually buying
When we pick Firestore, we are not picking a document store so we can feel modern. We are buying listeners, offline cache, and a security model we can ship without standing up a socket layer on day four.
That matters when the person writing the update is in the field, on a bad network, on a phone that will sleep. We have shipped Flutter apps where the whole point was: the status in the phone is the status. If that update dies in a queue behind a custom API, the product is a rumor.

A typical watch in our apps looks like this. It is not clever. It is the product.
Stream<Booth> watchBooth(String id) {
return FirebaseFirestore.instance
.collection('booths')
.doc(id)
.snapshots()
.map((doc) => Booth.fromJson(doc.data()!));
}
Three roles can subscribe to that without us inventing a protocol. I like that. I will not apologize for liking that.
The week Firestore starts arguing with you
It always starts with a report.
Someone wants "all booths that were delayed last month, grouped by agent, exported for a meeting." That sentence is reasonable. It is also the moment you notice you have been modeling for listeners, not for joins. You add a composite index. Then another. Then you denormalize a name onto a second document because you cannot join, and now a rename has two writes, and one of them will be forgotten at 11pm.
We have hit the other walls too.
- Queries that are obvious in SQL and fussy in Firestore.
- Migrations that are "write a script and pray the clients can read both shapes."
- A console that makes it too easy to treat production like a scratch pad.
- Costs that stay cute until a chatty screen stays open on fifty phones.
None of this means Firestore is bad. It means we used a live database as a warehouse. That is on us.

The line I actually use
I say this out loud in scoping calls now, before anyone opens the Firebase console.
If the product is a live shared picture, Firestore. Presence, status, a document a few people must see change. Flutter clients. Offline. Security rules that match roles you can name.
If the product is a ledger, a catalog, or a report, SQL. Orders, inventory history, anything you will later ask to group, join, or prove.
If it is both, do not pretend one database is a personality. Live state in Firestore. Facts you will audit or aggregate somewhere that likes tables. A worker copies what it must. The client does not run analytics queries because the dashboard looked empty.
We have done the hybrid on purpose. We have also done the hybrid by accident, which is how you get a Cloud Function that exists only to turn documents into rows, written in a hurry, named syncThing. I am trying to write fewer functions named syncThing.
Rules that saved us from ourselves
A few habits. None of them are original. All of them are cheaper than a rewrite.
- Documents are for a screen, not for a future warehouse.
- If two clients must agree on a field, that field has an owner. The other client does not "also update it sometimes."
- Security rules get reviewed like API code. A collection that is readable by any signed-in user is a product decision, not a default.
- We do not put a list of 8,000 ids in one document because it was convenient on Tuesday.
- When someone says "we will just export it later," we put a date on later.
I am not loyal to the logo
Firebase has been good to us. This site talks to Firestore. Some of our mobile work would have shipped later without it. I still will not die on a hill that says every product should start there.
The religion is the problem. Teams pick a database the way they pick a haircut, then spend a year defending the haircut. I want the constraint I can live with. For a booth that has to flip from "not ready" to "ready" while three people are watching, I will take the listener. For the spreadsheet the finance person is going to email me anyway, I will take the table.
If you are choosing Firestore because the tutorial was short, that is fine for a week. After that, choose it because your product is live. Or choose something else, and stop asking the live database to be your warehouse after the fact.