Flutter + Firebase for SaaS Mobile Apps in 2026
A Flutter and Firebase SaaS stack buys you one Dart codebase across six platforms and a backend you never provision. It leaves you two problems that are genuinely hard: tenant isolation and billing.
I have been running that stack in production on BookBed, the property management SaaS I built solo, since October 16, 2025. The same Dart code compiles to iOS, Android, Web, macOS, Linux and Windows. Firestore holds the data, Cloud Functions handle anything money touches, Stripe takes the payment. Six months and forty-plus screens later, the parts that hurt were not the parts the tutorials warn about. Nobody warned me that the deep-linking product Google recommended in every Flutter tutorial would be returning HTTP 404s before the app turned one.
So this post covers what a Flutter and Firebase SaaS mobile stack actually contains, where Firebase quietly bills you, the one architectural decision you cannot undo, and the two things that changed in the last twelve months that most Flutter SaaS advice has not caught up with.
What Does a Flutter + Firebase SaaS Stack Actually Include?

A production Flutter and Firebase SaaS needs six layers: auth with tenant claims, a tenant-scoped datastore, server-side functions, a billing broker, message delivery, and crash telemetry. Miss one and it surfaces as an incident rather than a missing feature.
- Auth. Firebase Authentication, with a custom claim on the token naming the tenant. Apple Sign-In becomes mandatory on iOS the moment you offer any other social provider, so budget for it before you ship, not during review.
- Data. Cloud Firestore for document-shaped data, or Firebase SQL Connect when the domain is genuinely relational.
- Server. Cloud Functions. Every webhook, every privileged write, every claim mutation. The client never writes its own subscription status.
- Billing. RevenueCat, Stripe, or both. People get this one wrong, and not in the way they expect.
- Delivery. Firebase Cloud Messaging for push, plus a transactional email provider. BookBed runs eighteen-plus Resend templates alongside FCM, because a booking confirmation is an email problem and a check-in reminder is a push problem.
- Telemetry. Crashlytics. A Flutter crash on a mid-range Samsung is otherwise invisible to you.
What is missing from that list is a state-management library, and the omission is deliberate. Riverpod, Bloc, Provider — pick one and stop reading comparison posts. None of them is why a SaaS fails.
Firestore, SQL Connect, or Supabase for a Firebase SaaS Backend?

Pick Firestore when your data is document-shaped and your queries are known in advance; pick SQL Connect when you need joins, aggregates, or window functions.
This question is live again because Firebase Data Connect was renamed Firebase SQL Connect at Cloud Next on April 29, 2026, picking up realtime query subscriptions through an @refresh directive, offline caching, and the option to drop raw SQL into .gql operation files (Firebase blog). Operations were repriced to $0.90 per million from May 1, down from $4.00, with 250,000 free per month on Blaze. Managed Postgres with realtime subscriptions inside the Firebase console is a materially different offer than it was a year ago.
| Option | Best when | Free tier | Where it hurts |
|---|---|---|---|
| Cloud Firestore | Document-shaped data, offline-first mobile, query paths known at design time | 50K reads, 20K writes, 20K deletes per day, 1 GiB stored | No joins; per-read billing punishes list screens |
| Firebase SQL Connect | Relational domains, reporting, joins across a tenant's own records | 250K operations/month, 90-day Cloud SQL trial | You now pay for a Cloud SQL instance that does not scale to zero |
| Supabase | You want Postgres with row-level security and will leave the Firebase console | 500 MB database, two free projects | Flutter offline support is thinner; you rebuild the FCM and Crashlytics equivalents |
Firestore quotas above come from Firebase pricing. The number that catches people is reads, not writes. A dashboard rendering a list of forty bookings costs forty reads every time someone pulls to refresh, and a 50,000-a-day allowance evaporates faster than you would guess once a handful of tenants develop a refresh habit.
Multi-Tenancy Is the One Thing You Cannot Retrofit

Put the tenant ID in the document path before you write your first screen, because moving it there later means migrating every document, index, rule and query at once.
Firebase documents the mechanism: a custom claim on the auth token, read back inside Security Rules as request.auth.token.<claim> (Firebase docs). For a tenant boundary that becomes a tenant_id claim compared against the tenant segment of the path, and writing it is an afternoon of work. The part that trips teams is subtler. Google's own wording is that "security rules are not filters — queries are all or nothing," and Firestore evaluates a query against its potential result set rather than the documents it would actually return (Firestore docs). A collectionGroup query spanning tenants therefore does not quietly hand back the caller's own subset. It is denied outright.
Actually, that undersells the consequence. The tenant ID has to live in the query as well as the rule, which means it has to live in the path or an indexed field, which means the decision is made at schema-design time and then enforced by every read you ever write. There is no version of this you bolt on in month four.
The cost of getting it wrong does not arrive on day one. It arrives the day you add your first cross-tenant admin screen, reach for collectionGroup because nothing else works, and write a rule to permit it that is broader than the rule it replaced.
Do You Need RevenueCat for a Flutter Subscription App?
RevenueCat earns its place the moment you sell on both App Store and Play, because cross-store receipt validation and subscription reconciliation is a real backend product.
It is free up to $2,500 in monthly tracked revenue, then 1% of tracked revenue (RevenueCat pricing). Several comparison posts still quote a $99-a-month Grow tier that the first-party pricing page does not list. Check any RevenueCat number you read elsewhere against that page.
| Approach | Setup cost | Ongoing cost | Covers |
|---|---|---|---|
in_app_purchase package, direct | High. You build receipt validation, renewal handling and grace-period logic yourself | Store commission only | iOS and Android only |
| RevenueCat | Low. SDK plus a dashboard entitlement model | Free to $2,500 MTR, then 1% of tracked revenue | App Store, Play, and web billing it brokers |
| Stripe, direct | Medium. Webhooks and a subscription state machine you own | Payment processing fees | Web and desktop; not a legal path for iOS digital goods |
The last row is the one that decides your architecture. RevenueCat covers the surfaces it brokers, and a Flutter product shipping to macOS, Linux, Windows and web has surfaces it does not. BookBed bills through Stripe for exactly that reason, with cross-tab checkout resolved by a BroadcastChannel listener and a Firestore listener as the authoritative fallback, because webhook writes are the only thing permitted to move an account's status. Two billing systems, not one. The Flutter, Firebase and RevenueCat stack breakdown covers the mobile-only path where one is enough.
One number before you build any of it. RevenueCat's State of Subscription Apps 2026, drawn from more than 115,000 apps and $16 billion in tracked revenue, puts the global median download-to-paid conversion at 2.0% and finds that 4.6% of apps reach $10,000 in monthly revenue within two years (RevenueCat). Build the billing layer that fits the median outcome first, and earn the complicated one.
Deep Links Are Now Your Problem
Firebase Dynamic Links shut down on August 25, 2025. Every .page.link URL and custom FDL domain now returns HTTP 404, and the link metadata was purged (Firebase FAQ). No redirect. No grace period.
You shipped the app; a user taps a shared invite link. What happens? App Links and Universal Links handle it when the app is installed. When it is not, you need deferred deep linking, and Google's answer there is a paid third party.
The App Store Tax Is Unsettled, Which Changes the Math
United States link-outs to your own web checkout are currently permitted with no Apple commission, but that state is provisional and the case is still moving.
The sequence matters if you are pricing a Flutter subscription app right now. Judge Gonzalez Rogers found in April 2025 that Apple had willfully violated the 2021 injunction and barred commissions on external purchase links. In December 2025 the Ninth Circuit affirmed the contempt findings but vacated the total ban, remanding so the district court could set a rate tied to Apple's actual costs (MacRumors). The Supreme Court then granted certiorari in mid-2026 on the narrow question of whether a party can be held in contempt for violating the spirit of an injunction.
For a Flutter SaaS this is an architecture question, not a legal one. If your web checkout already exists because you ship to desktop and browser anyway, a US link-out costs you nothing to add and can be removed in a config flag if the rate changes. If your only surface is mobile, do not build a web billing stack on the assumption that today's zero-commission window survives a 2027 ruling.
What Flutter SaaS Architecture I Would Wire Up This Week
- Create the Firebase project and write Security Rules before the first screen. Tenant ID in the path, custom claim on the token, and emulator tests proving a second tenant is denied.
- Model documents as
tenants/{tenantId}/...even when you have exactly one tenant and no plans for a second. Especially then. - Route every privileged write through a Cloud Function. Subscription status, tenant claims, invitations. The client proposes; the function decides.
- Add RevenueCat if you are mobile-only, Stripe if you have a web or desktop surface, both if you have both. Reconciliation between them is now a standing job, so name an owner for it.
- Configure AASA and
assetlinks.jsonon day one, before anybody has a link to share. Deferred deep linking can wait a quarter; installed-app deep linking cannot wait a week. - Turn on Crashlytics before the first TestFlight build, not after the first crash report you cannot reproduce.
Tooling for all of that is deliberately boring, and the Flutter dev tools I actually keep installed is a short list. If what you are building is a template rather than a platform, the economics invert entirely — the FlutterFlow marketplace templates I ship run on a review-and-update cycle instead of a subscription state machine. And if you are still deciding whether this is a SaaS product or a one-off app, settle that first, because the tenancy model follows from the answer.
Six months in, BookBed's booking calendar repository is 989 lines carrying a comment pinned at the top that reads do not refactor without unit tests. The duplication underneath came from bugs fixed one at a time, and collapsing it would resurrect them. That is what a Flutter and Firebase SaaS looks like once it has been alive long enough to have scars.
Before You Open Your Editor
Open your Firestore data model and answer one question: if you onboarded a second tenant tomorrow, how many documents would have to move? Any answer above zero is your next sprint, and the number only grows from here.
What does your app's download-to-paid conversion actually look like against that 2.0% median?
