Connect FlutterFlow to Google Cloud Firestore using the built-in Firebase native integration — Firestore IS FlutterFlow's default database. Open the Firebase menu, link your Google project, define your collections in the Firestore schema editor, then bind ListViews and forms to your data with no-code Query Collection actions. Security Rules are the make-or-break step: replace the 30-day test-mode rules before launch.
| Fact | Value |
|---|---|
| Tool | Google Cloud Firestore |
| Category | Database & Backend |
| Method | FlutterFlow Native Integration |
| Difficulty | Beginner |
| Time required | 30 minutes |
| Last updated | July 2026 |
Firestore Is FlutterFlow's Native Database — Here's How to Use It
When most FlutterFlow builders talk about 'adding a database,' they mean Firestore. It is not a third-party integration you need to configure with API keys or REST calls — it is the database that ships with every Firebase project, and FlutterFlow has a dedicated schema editor, query builder, and action set built specifically around it. The result is that you can build a fully functional, real-time data-driven app without writing a single line of Dart.
Firestore's Spark free tier gives you 50,000 reads, 20,000 writes, and 1 GB of storage per day at no cost, making it ideal for early-stage apps and MVPs. When you need to scale, upgrading to the Blaze pay-as-you-go plan happens in Google Cloud console — but be aware that Blaze has no spending cap by default. Set a budget alert in Google Cloud immediately after upgrading to avoid surprise bills from a runaway query listener.
The feature that sets Firestore apart for FlutterFlow specifically is the tight connection between Firebase Auth and Security Rules. When a user logs in through FlutterFlow's Auth setup, their UID becomes available inside Firestore Rules as `request.auth.uid`. This lets you write a single rule like `allow read, write: if request.auth != null && resource.data.userId == request.auth.uid;` that ensures every user only sees their own documents — with no server code required.
Integration method
Firestore is not an external tool you bolt on to FlutterFlow — it is the built-in database when you use Firebase. FlutterFlow's Firebase panel lets you define collections and fields visually, generates StreamBuilder queries automatically, and wires Create/Update/Delete document actions to your widgets with no Dart required. Authentication state from Firebase Auth feeds directly into Firestore Security Rules, so logged-in users only see their own data.
Prerequisites
- A FlutterFlow project (free or paid plan)
- A Google account to create or access a Firebase project
- Firebase project created at console.firebase.google.com (or let FlutterFlow create one during setup)
- Owner or Editor role on the Firebase/Google Cloud project (Viewer access will not let FlutterFlow auto-generate config files)
- Firebase Authentication enabled if you plan to use auth-based Security Rules (recommended)
Step-by-step guide
Connect your Firebase project to FlutterFlow
In your FlutterFlow project, click the Firebase icon in the left toolbar — it looks like the Firebase flame logo. This opens the Firebase panel. Click 'Connect' and sign in with the Google account that has Owner or Editor access to your Firebase project. FlutterFlow will list all Firebase projects associated with that account. Select the project you want to use, then click 'Auto-generate Config Files.' FlutterFlow calls the Firebase Management API to download the google-services.json (Android) and GoogleService-Info.plist (iOS) files automatically and embeds them in your build. You will see a green checkmark next to 'Firebase Connected' in the panel when this succeeds. If it fails silently, it almost always means your Google account has Viewer-only access — the account connecting must have Owner or Editor permissions at the Google Cloud project level, not just the Firebase console.
Pro tip: If you do not yet have a Firebase project, you can create one from console.firebase.google.com before starting this step. Give it a name that matches your app — you cannot rename it later without breaking the connection.
Expected result: The Firebase panel in FlutterFlow shows a green 'Connected' badge and lists the Firebase services available to enable.
Enable Firestore and define your collections in the schema editor
Inside the Firebase panel, click the 'Firestore' tab. If Firestore is not yet enabled on the Firebase project, FlutterFlow will show a prompt to enable it — click it and choose a region close to your users (for example, us-central1 or europe-west1). Once enabled, you will see FlutterFlow's Firestore schema editor. Click '+ Add Collection' and give your first collection a name (for example, 'products' or 'tasks'). Collections hold your documents; think of them like database tables. Inside the collection, click '+ Add Field' to define each field: give it a name, choose a FlutterFlow data type (String, Integer, Double, Boolean, Timestamp, LatLng, Document Reference, or a custom Data Struct you define), and mark whether it is nullable. Document References are especially powerful — a 'userId' field of type Document Reference pointing to the 'users' collection creates a relational link between documents. Add all the fields your app will need. FlutterFlow will generate the type-safe Dart models from this schema automatically, saving you from writing boilerplate code.
Pro tip: Keep collection names lowercase and plural (tasks, products, users). FlutterFlow uses these names to generate Dart class names, so consistent naming makes the generated code easier to read.
Expected result: Your collection appears in the Firestore schema editor with all its fields listed and typed. FlutterFlow shows a preview of the generated Dart data type.
Set production Security Rules — do not skip this
This is the most important step and the one most often skipped. In the Firebase panel, click 'Firestore' then 'Settings.' You will see the Security Rules editor. When you first enable Firestore, Google puts it in test mode with a rule that reads: `allow read, write: if request.time < timestamp.date(YEAR, MONTH, DAY);` — this rule allows any unauthenticated person to read and write ALL of your data until the expiry date, which is typically 30 days after you enabled Firestore. You must replace this with real rules before you go live. A safe starting rule for apps using Firebase Auth looks like this: for a 'tasks' collection where each document has a userId field, the rule is `allow read, write: if request.auth != null && resource.data.userId == request.auth.uid;`. For the create operation, use `request.resource.data.userId == request.auth.uid` instead of `resource.data.userId` because `resource.data` refers to the existing document, which does not exist yet on a create. After editing, click 'Save Rules.' The changes deploy to Firebase within a few seconds. You can test your rules in the Firebase console under Firestore → Rules → Rules Playground without having to run the actual app.
1rules_version = '2';2service cloud.firestore {3 match /databases/{database}/documents {4 // Users can only read and write their own task documents5 match /tasks/{taskId} {6 allow read, update, delete: if request.auth != null7 && resource.data.userId == request.auth.uid;8 allow create: if request.auth != null9 && request.resource.data.userId == request.auth.uid;10 }11 // Users can read and write their own profile12 match /users/{userId} {13 allow read, write: if request.auth != null14 && request.auth.uid == userId;15 }16 }17}Pro tip: If you need complex rules or composite index design and want help, RapidDev's team works on FlutterFlow + Firestore integrations regularly — free scoping call at rapidevelopers.com/contact.
Expected result: The Firebase console shows your new rules are published. The Rules Playground in Firebase console confirms that an authenticated user can access their own documents but an unauthenticated user is denied.
Bind a ListView to a Query Collection for real-time data
Navigate to the page in your FlutterFlow app where you want to display your Firestore data. Add a ListView widget from the widget panel. Click the ListView to select it, then open the Backend Query panel on the right side. Click '+ Add Query' and choose 'Query Collection' as the query type. In the dropdown, select the collection you defined in the schema editor (for example, 'tasks'). You can add Filter conditions — for example, filter where userId equals the authenticated user's UID by clicking '+ Filter,' selecting the 'userId' field, choosing 'Equal To,' and setting the value to 'Authenticated User → User Reference.' You can also add Order By (for example, created_at Descending) and a Limit. Click 'Confirm.' FlutterFlow generates a StreamBuilder under the hood, so the list updates in real time whenever a document in the collection changes — no pull-to-refresh button needed. Inside the ListView, add your UI widgets (Text, Image, etc.) and bind each one to a field from the query result using the variable picker.
Pro tip: If you add a Filter that uses more than one field (for example, userId AND status), Firestore will require a composite index. FlutterFlow will show a warning with a link to auto-create the index in the Firebase console — click that link and the index builds in a few minutes.
Expected result: The ListView shows a live list of your Firestore documents on the page canvas. In Run mode, documents appear instantly and new ones added elsewhere show up without refreshing.
Add Create, Update, and Delete Document actions to forms and buttons
Now wire up write operations. For a Create: add a Form widget (or individual TextField widgets) to a new page, then add a Button. Click the Button, open the Action Flow Editor (the Actions panel on the right side), click '+ Add Action,' and choose 'Backend/Database → Create Document.' Select your target collection, then map each document field to the corresponding form input using the variable picker. For example, map 'title' to the TextField's value and 'userId' to Authenticated User → User Reference. For an Update: on a detail page that receives the document as a page parameter, use a similar Action Flow with 'Update Document' instead — set the Document Reference from the page parameter and map only the fields you want to change. For a Delete: add a Delete button, set its action to 'Delete Document,' and point it at the document reference from the page state or parameter. All three action types run client-side using the authenticated user's Firestore session, so your Security Rules govern whether the operation is allowed — they are your last line of defense.
Pro tip: Use Document References (not String IDs) when pointing to related documents. FlutterFlow resolves Document References automatically in queries, saving you from manually building query paths.
Expected result: Submitting the form creates a new document that immediately appears in any ListView bound to that collection. The Firebase console's Firestore data viewer confirms the new document is present with all fields correctly populated.
Common use cases
Marketplace app where sellers list products and buyers browse in real time
A FlutterFlow marketplace app stores product listings as Firestore documents. Sellers fill in a form that triggers a Create Document action; buyers see an automatically updating ListView bound to a Query Collection filtered by category. Security Rules ensure only the seller who created a listing can edit or delete it.
Build a marketplace app where users can post items for sale with a title, price, and photo. Other users should see a live-updating list of all available items and be able to tap to view details.
Copy this prompt to try it in FlutterFlow
Task management app with per-user to-do lists
Each user's tasks are stored as documents in a 'tasks' collection with a userId field. A Query Collection filtered to the logged-in user's UID populates their personal task list. A form with a Create Document action lets them add new tasks, and a swipe gesture fires a Delete Document action.
Create a to-do list app where each logged-in user sees only their own tasks. Users can add, complete, and delete tasks. The list should update instantly without a refresh button.
Copy this prompt to try it in FlutterFlow
Community event board with RSVP counter
Events are stored as Firestore documents with an attendeeCount integer field. Users tap an RSVP button that fires an Update Document action using FieldValue increment. A real-time listener on the ListView keeps the count current for all users viewing the same event simultaneously.
Build an event board where admins can post upcoming events and users can RSVP. The RSVP count should update live as people register, without needing to reload the screen.
Copy this prompt to try it in FlutterFlow
Troubleshooting
ListView shows empty list in Run mode or on device, even though documents exist in Firebase console
Cause: A composite index is missing for the query's Filter + Order By combination, or Security Rules are blocking the read for the current user's auth state.
Solution: Open the debug console in FlutterFlow (Run mode → Debug panel) or the Firebase console's Firestore → Usage tab. For a missing index, you will see a URL in the console — click it to auto-create the index in Firebase. For a Security Rules denial, open Firestore → Rules → Rules Playground in the Firebase console and simulate the read with your test user's UID to find the rule that is failing.
Create Document action fails with 'PERMISSION_DENIED' error at runtime
Cause: Your Firestore Security Rules block the write. Common cause: the rule checks resource.data.userId on a create operation, but resource.data does not exist yet for a new document.
Solution: In your Security Rules, use request.resource.data.userId for the create case and resource.data.userId for read/update/delete. Deploy the corrected rules from the Firebase panel in FlutterFlow or directly in the Firebase console.
1// Wrong for create:2allow create: if resource.data.userId == request.auth.uid;34// Correct:5allow create: if request.resource.data.userId == request.auth.uid;Data was publicly readable or writable before launch — test-mode rules were live
Cause: The default 30-day test-mode Security Rules (`allow read, write: if request.time < ...`) were never replaced. Any unauthenticated user could read and write all Firestore data during that window.
Solution: Replace the test-mode rules with auth-based rules immediately (see Step 3 above). Rotate any sensitive data that may have been exposed. Go to Firestore → Rules in the Firebase console, remove the time-based rule, add proper auth checks, and click Publish.
Firestore read quota hit unexpectedly — app shows 'Quota Exceeded' errors
Cause: A ListView with a Query Collection listener on a large collection without a tight Filter is reading every document on every snapshot update, burning daily quota fast.
Solution: Add a Filter to your Query Collection to narrow results (for example, filter by userId so each user only loads their own documents). Add a Limit to cap the number of documents returned. For paginated lists, use the 'Paginate' option on the Query Collection instead of loading all documents at once. If you are on Spark and need more quota, consider upgrading to Blaze and setting a budget alert.
Best practices
- Replace the default 30-day test-mode Security Rules with auth-based rules before you share the app with anyone — this is the single most important production step.
- Set a budget alert in Google Cloud console immediately after upgrading to the Blaze plan. Firestore's Blaze tier has no spending cap by default, and a runaway listener can generate real charges.
- Use Document References for relational links between collections instead of storing raw string IDs — FlutterFlow resolves them automatically and they stay valid even if document paths change.
- Add a Filter to every Query Collection that restricts results to the current user (userId == currentUser.uid) to avoid reading documents you do not need and burning daily quota.
- Use composite indexes only when needed (multi-field Filter + Order By). Each composite index costs storage and write overhead, so add them on demand using the auto-create link from the Firestore error rather than pre-creating all combinations.
- Test Security Rules in the Firebase console Rules Playground before deploying — it shows you exactly which rule allows or denies a simulated operation without running the app.
- Keep Firestore documents small (under 1 MB). Store large media in Firebase Storage and save only the download URL in Firestore. Fetching a large document counts as a read regardless of how little of the data you display.
Alternatives
Choose MongoDB Atlas if you need flexible document schemas and complex aggregation pipelines, but note it requires a custom backend proxy since FlutterFlow has no native Mongo driver — Firestore needs no proxy.
Choose PostgreSQL (via Supabase) if you prefer relational data with SQL joins and Row Level Security — Supabase is also natively supported in FlutterFlow, similar to Firebase.
Choose Airtable if your team needs a spreadsheet-style UI for managing data without writing any rules — Airtable is simpler to manage but requires REST API calls from FlutterFlow rather than a native integration.
Frequently asked questions
Is Firestore the same thing as Firebase? Do I need a separate account?
Firestore is one service inside the Firebase platform, not a separate product. When you create a Firebase project, you get access to Firestore, Firebase Auth, Storage, Cloud Functions, and more under one Google account. You do not need a separate Firestore account — it is all managed through console.firebase.google.com.
Can I use Firestore without enabling Firebase Authentication?
Technically yes, but it means your Security Rules cannot check who is making a request. You would have to use open rules (which expose data publicly) or write complex custom token schemes. The strongly recommended pattern is to enable Firebase Auth first, then base your Security Rules on request.auth.uid to ensure each user only accesses their own data.
Why does my filtered ListView return empty results on device but shows data in the FlutterFlow canvas preview?
The canvas preview in FlutterFlow often uses mock data that ignores Security Rules and index requirements. On a real device or in Run mode, the actual Firestore rules and indexes apply. Check the debug console for a missing-index URL or a PERMISSION_DENIED error and address those first.
Will Firestore data update in real time without the user pulling to refresh?
Yes — FlutterFlow's Query Collection uses Firestore's real-time listener (a StreamBuilder in the generated Dart code). Any change to a document in the collection — whether made by another user, a Cloud Function, or the Firebase console — pushes instantly to all connected app screens that are listening to that collection.
What is the free tier limit for Firestore, and when do I need to upgrade?
The Spark (free) plan gives you 50,000 document reads, 20,000 writes, 20,000 deletes, and 1 GB of storage per day. For an MVP or low-traffic app this is usually plenty. When you start approaching those limits regularly, upgrade to Blaze (pay-as-you-go) — but set a Google Cloud budget alert immediately because Blaze has no default spending cap.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation