Skip to content
← Back to the blog
securityapps

Firebase security rules in FlutterFlow: set them up right

How FlutterFlow's Firestore rule options work, which defaults to change before launch, how to stop users editing their own role, and how to test and deploy.

By Devonauts Team6 min read
Leer en español →
A hand types a passcode on a smartphone lock screen lying on a wooden table next to a glass of tea

In a FlutterFlow app, Firestore security rules are the only thing that stops one user from reading or changing another user's data, because the app talks to the database directly from the phone. FlutterFlow lets you set, for each collection, who can create, read, write and delete documents, and generates the rules when you click Deploy. Before launch, check every collection: nothing private should be readable by Everyone, user-owned data should use Tagged Users or Users Collection, the temporary test-mode rule must be gone, and users must not be able to edit fields like their own role.

This guide explains each option, the mistakes that show up most often, when to write a custom rule, and how to test and deploy without locking yourself out.

Why do security rules matter so much in FlutterFlow?

A FlutterFlow app with Firebase has no server of its own between the user and the database. The app on the phone queries Firestore directly, and anyone can take your app's Firebase configuration and send their own requests. Hiding a button or filtering a list in the UI does nothing against that. The rules are checked by Firebase on every request, which makes them your real permission system.

What do FlutterFlow's rule options mean?

You find them in FlutterFlow's Firestore settings, in the Firestore Rules section. Each collection has four operations: Create, Read, Write (update) and Delete. For each, you pick one access level:

OptionWho is allowedTypical use
EveryoneAnyone, signed in or notTruly public content, like a published catalog
Authenticated UsersAnyone who is signed inContent every member may see
Tagged UsersUsers referenced in a field of the documentPosts, orders or notes owned by a user
Users CollectionThe user whose ID matches the document IDThe users collection only
No OneNobody from the appData only your backend should touch

Tagged Users needs a field on the document that holds a reference to the user or a string with the user's ID, such as created_by. When you choose it, FlutterFlow opens a Tag Users popup where you select that field. Make sure the app actually fills the field when it creates the document, or nobody will match.

Which defaults should I change before launch?

New collections may start more open than you think

FlutterFlow's docs list the defaults for a new collection with Create and Read set to Everyone. That's fine for a demo and wrong for most real data. Go through every collection and ask: should someone who isn't signed in be able to read this? For orders, messages, notes and profiles, the answer is no.

FlutterFlow also flags collections that may hold personal information as Has Private Data and warns you to restrict them. Don't dismiss that warning without looking.

The test-mode rule must go

When a Firestore database is created in test mode, it starts with a rule like allow read, write: if request.time < ..., which lets anyone do anything until a date. FlutterFlow's docs say to remove it and leave test mode before publishing. Open the Rules tab of Firestore in the Firebase console and confirm it's gone.

"Authenticated Users" is not "the owner"

Setting Read or Write to Authenticated Users means any signed-in user, including someone who signed up five minutes ago, can read or change every document in that collection. For anything that belongs to one person, use Tagged Users on Read, Write and Delete.

How do I stop users from changing their own role?

This one is easy to miss. If your users collection uses Users Collection for Write, each user can edit their own document, and that includes any field on it. If you keep a field like role, is_admin or plan there, a user can set it to whatever they like with a single request.

Two fixes:

  1. Move privileged fields to a collection the app can't write to (Write set to No One), and change them only from a backend, such as a Cloud Function.
  2. Or exclude the collection from FlutterFlow's generated rules and write a custom rule that blocks changes to those fields:
match /users/{userId} {
  allow read: if request.auth != null && request.auth.uid == userId;
  allow update: if request.auth != null && request.auth.uid == userId
    && !request.resource.data.diff(resource.data).affectedKeys()
        .hasAny(['role', 'is_admin', 'plan']);
}

When should I write custom rules?

FlutterFlow's options cover ownership well. They don't cover everything. Write custom rules when you need:

  • Roles, for example admins who can read all orders: allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin';
  • Field checks on create, such as making sure a new order's created_by is the person creating it, so nobody can create documents in someone else's name.
  • Shared access, such as team members who can all read a project.

To do it, tick Exclude for that collection in FlutterFlow, so it stops generating a rule for it, and write the rule in the Firebase console under Firestore Database, Rules. Firebase's security rules documentation explains the syntax. Keep a copy of your custom rules in your project notes or repository.

How do I deploy and test the rules?

Rules only take effect once deployed. In FlutterFlow, click Deploy; a review window shows the rules before and after the change, and Deploy Now applies them. Read that comparison every time, especially if you also edit rules in the console, so a deploy doesn't quietly replace something you wrote by hand.

Then test like an attacker would:

  1. Create two test accounts, A and B.
  2. With A, create a document in each private collection.
  3. Sign in as B and try to open A's documents, for example through a page that takes a document ID.
  4. Try the same signed out.
  5. Use the Rules Playground in the Firebase console to simulate reads and writes as a specific user.

If something breaks after a deploy, you can roll back in the Firebase console: open the Rules tab, pick the previous ruleset from the history on the left, paste it in and click Publish. If a deploy fails with "cloud resource location is not set", FlutterFlow's docs point to setting the Default GCP Resource Location in the Firebase project settings after Firestore has been set up.

Remember that Firebase Storage has its own rules for uploaded files, set separately from Firestore's. Check them too.

Quick answers

Do I need security rules if my FlutterFlow app hides data in the UI? Yes. The app reads Firestore directly, so anyone with your Firebase config can bypass the UI. Only the rules are enforced.

What does Tagged Users mean in FlutterFlow? Access is limited to the user referenced in a chosen field of the document, such as created_by.

Why can't my users see their data after I changed the rules? Usually the owner field is empty or holds a different value than the rule expects, or the new rules weren't deployed.

Can I edit rules in the Firebase console instead of FlutterFlow? Yes, for collections you mark as Excluded. Review FlutterFlow's before-and-after view on every deploy.

Want your rules checked?

Rules are short, but one wrong option can expose every user's data. Our FlutterFlow app service reviews rules, data structure and custom code, and our mobile app development team can take on larger work. Read what to do when a user can see other users' data and our security checklist for AI-built apps, or contact us.

Still stuck with your app?

Run the free health check on your app's URL, or get the $299 App Rescue Audit: a senior engineer reviews the code and sends you a written report in 2 business days.