8 min read
FlutterFlow to production: custom code, Firebase rules and App Store review
A FlutterFlow app that looks finished in the builder still needs three workstreams before it is production-ready: isolated custom code, Firebase rules that match real roles, and a release process that survives store review.
Going from FlutterFlow to production means three things beyond finished screens: custom code that is small, tested and isolated; Firebase rules and functions that enforce who can read and write what; and a release process that gets signed builds through App Store and Google Play review. Treat each as its own workstream with its own checks.
This guide follows on from when to hire a FlutterFlow developer and the FlutterFlow App Store post. It is a practical checklist drawn from FlutterFlow expert practice and from Firebase behavior observed in this portal's own code, not a guarantee that any app will pass review.
Why finished in the builder is not production
The FlutterFlow canvas shows what users will see. It does not show whether a signed-in user can read another user's records, whether a payment secret is embedded in the app, or whether the build uploaded to Apple carries the right identifier. Those properties live in Firebase configuration, generated code and store settings, and the builder's preview exercises very little of them.
Prototypes are also built under different assumptions. Open security rules make development easy. Test accounts share data. A single environment serves development and real users. Each shortcut is reasonable early and dangerous at launch, and none of them is visible from the screens.
What teams often get wrong
- Shipping with development-era security rules because the app works with them.
- Putting privileged logic, such as granting a subscription or calling an AI provider with a secret key, in client-side custom actions.
- Using one Firebase project for development and production, so tests write into real users' data.
- Assuming that a finished deploy in FlutterFlow means a build reached App Store Connect.
- Discovering store requirements, such as account deletion or privacy declarations, from a rejection email.
A production architecture for a FlutterFlow app
A sound structure keeps the FlutterFlow client thin, moves trust decisions to the backend, and treats release as configuration you control.
Client: screens plus small custom code
Keep FlutterFlow responsible for screens, navigation and straightforward reads and writes. Custom widgets, actions and functions should be small, single-purpose and named for what they do. Anything that needs a secret or must be trusted belongs on the server.
Backend: rules, functions and App Check
Firestore and Storage security rules decide who can read and write each document and file. Cloud Functions handle privileged operations: payments and subscription changes, notifications, scheduled jobs, AI calls and anything that touches another user's data. App Check adds an attestation that requests come from your genuine app, using the platform attestation services on iOS and Android.
Release: environments, identifiers and signing
Use separate Firebase projects for development and production, separate bundle identifiers where appropriate, and a clear record of which build points at which backend. Store credentials, signing configuration and store listings should sit under your organization's accounts, with access documented.
Firebase rules that match real roles
Start from denial and open access deliberately. Write rules per collection that check the signed-in user and the relationship between that user and the document: owner, member of a team, administrator. Role information used in rules should come from a source the user cannot edit, such as custom claims set by a backend function or a server-maintained document.
Remember that rules are not filters. A query that could return documents the user is not allowed to read is rejected as a whole, so queries in the app must include the same constraints the rules check. This is a frequent source of pages that suddenly show nothing once rules are tightened.
Validate writes, not only reads. Rules can check that a user cannot change fields such as a role, a subscription status or an owner ID, and that required fields have sensible types. Test all of this with the Firebase emulator before deploying, including attempts that should fail.
Custom code that survives regeneration
FlutterFlow regenerates code from the project, so custom code must live in the places the builder provides for it and must not depend on editing generated files. Keep dependencies explicit, pin package versions that are known to work with the project's Flutter version, and avoid packages that require native configuration the builder cannot express unless you are ready to handle that configuration yourself.
Test custom code on real devices in release mode. Behavior around permissions, background execution and platform channels often differs between a debug preview and a signed release build.
App Store and Google Play review
Most rejections are predictable. Before submission, check the following:
- The production archive carries the production bundle identifier, not a development one.
- The App Store Connect API key used for uploads has an appropriate role and belongs to the right team.
- Every permission the app requests has a clear usage description that matches what the feature does.
- Apps that let users create accounts also let them delete their account from within the app.
- Privacy details in App Store Connect and the Google Play data safety form match what the app actually collects.
- Reviewers get a working demo account and notes explaining any feature that is hard to reach.
- Apple's rules on offering Sign in with Apple alongside other social sign-in options have been checked for your case.
- The Android build targets a currently accepted API level, and new developer accounts have satisfied any testing requirements Google applies before production access.
Treat the rejection message as a specification. It usually names the guideline involved, and addressing it precisely is faster than resubmitting with small unrelated changes.
Trade-offs
Strict rules and App Check make the app safer and occasionally make development slower: you will spend time on permission-denied errors that open rules would have hidden. Debug tokens and emulator testing reduce that friction, and the cost is worth paying before real users arrive.
Moving logic into Cloud Functions adds a backend to maintain, with its own deployment and monitoring. In exchange you get secrets that stay on the server, logic that can be changed without an app release, and a cleaner path if you export the app later.
Separate environments add setup work and some duplicated configuration. The alternative, testing against production data, is a much larger risk for any app with real users.
Lessons from ImadDhin work
The following are implementation-level observations from Firebase work, including this portal, and from public FlutterFlow release work. They are not claims about client apps.
A common Firebase finding is a project with more than one Firestore database. Security rules are deployed per database, and a rules file that is correct on one database does nothing for another. Public reads can fail with permission errors even when the rules look right, simply because they were never deployed to the database the client is using. List the databases in the project, deploy rules to each, and make that part of the release checklist.
When App Check enforcement is turned on for Firestore, clients that do not obtain a valid token receive permission-denied errors that look exactly like rules failures. Local development needs a registered debug token. Diagnosing this as a rules problem wastes time, so check App Check status first when permissions break right after enforcement is enabled.
Defaults in data matter as much as rules. Public listing queries in the portal treat a missing published flag as visible and hide only explicit drafts, which avoids content silently disappearing when an import script forgets a field. Decide your defaults deliberately and make seed scripts write them explicitly.
On the release side, the patterns in the FlutterFlow App Store post, a development identifier in the production archive, an API key without the right role and missing privacy strings, are the first checks when a deploy reports success but TestFlight stays empty.
Common mistakes to test for
- Sign in as one user and try to read and edit another user's documents and files.
- Try to change your own role, subscription status or owner field from the client.
- Search the built app for secret keys and admin credentials.
- Confirm the production build points at the production Firebase project.
- Turn on App Check in a staging project first and confirm the real app still works.
- Delete a test account from inside the app and confirm its data is handled as your privacy policy says.
- Install the release build on a clean device and walk through the first-run flow, including permission prompts.
When a simpler solution is better
An internal tool used by a small known team, distributed through an enterprise or testing channel, does not need the full public-store checklist. Tight rules and separate environments still matter, but listing and review preparation may not apply.
If the app is an early prototype for a handful of testers, avoid over-engineering the backend. Lock down the rules, keep secrets off the client, and postpone the rest until you know the product is worth taking further.
Ship the FlutterFlow app you already built
Work through the three workstreams, custom code, Firebase rules and release, before calling the app finished. If you want help, see how ImadDhin works as a FlutterFlow expert on stalled apps, Firebase security and store release, or book a 30-minute call with your project link and the rejection or error you are facing.
Frequently asked questions
What does it take to move a FlutterFlow app to production?
Three workstreams beyond screens: small, isolated custom code; Firebase rules and functions that enforce real roles and keep secrets on the server; and a release process with correct identifiers, signing, privacy details and store metadata.
Why did my FlutterFlow app show empty pages after I tightened Firestore rules?
Rules are not filters. A query that could return documents the user cannot read is rejected entirely. Add the same constraints the rules check to the query, and confirm the rules were deployed to the database the app actually uses.
Do I need App Check for a FlutterFlow app?
It is strongly recommended for production because it helps ensure requests come from your genuine app. Roll it out in staging first and register debug tokens for development, since unverified clients receive permission errors once enforcement is on.
What are the most common App Store rejections for FlutterFlow apps?
Missing or vague permission usage descriptions, no in-app account deletion when accounts can be created, privacy details that do not match the app, and reviewers unable to sign in. Upload failures are often bundle identifier or API key problems rather than rejections.
Should I use separate Firebase projects for development and production?
Yes, for any app with real users. It keeps test data out of production, lets you trial rules and App Check safely, and makes it clear which build points at which backend.
Get your FlutterFlow app production-ready
Custom code, Firebase rules and store release for stalled apps.
Hire a FlutterFlow ExpertBring the project link and the error. Leave with a plan.
Book a 30-minute callKeep reading
FlutterFlow App Store stuck: deploy says finished, TestFlight never gets the build
The community thread is always the same: FlutterFlow shows finished, history shows publishing failed, and nothing appears in App Store Connect. Here is what actually blocks it — and how to get a FlutterFlow Expert to finish the release.
Hire a FlutterFlow developer: when FlutterFlow fits, when to export code
FlutterFlow is fast for screens and standard data flows, and it gets harder around custom logic, release engineering and team workflows. Here is how to decide what kind of help you need, and when exporting code is the right call.
Firebase vs Supabase for AI products
Firebase is strongest for mobile-first products that need realtime sync, push and a managed Google ecosystem. Supabase is strongest when your AI features lean on relational data, SQL and vector search in Postgres. Here is how to choose by workload.