Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Protect Your FlutterFlow App from Unauthorized Access

Protect a FlutterFlow app from unauthorized access using layered controls: enable the Authentication Gate in FlutterFlow Settings to block unauthenticated users at launch, add On Page Load route protection for sensitive screens, write strict Firestore Security Rules that enforce ownership server-side, verify tokens in Cloud Functions for API endpoints, and sign users out after 15 minutes of inactivity.

What you'll learn

  • Enable FlutterFlow's Authentication Gate to block all unauthenticated users at app launch
  • Add On Page Load route protection to redirect unauthorized users from sensitive pages
  • Write Firestore Security Rules that enforce access control server-side
  • Implement inactivity timeout sign-out to protect unattended devices
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner9 min read25-35 minFlutterFlow Free+March 2026RapidDev Engineering Team
TL;DR

Protect a FlutterFlow app from unauthorized access using layered controls: enable the Authentication Gate in FlutterFlow Settings to block unauthenticated users at launch, add On Page Load route protection for sensitive screens, write strict Firestore Security Rules that enforce ownership server-side, verify tokens in Cloud Functions for API endpoints, and sign users out after 15 minutes of inactivity.

Multi-Layer Access Control for FlutterFlow Apps

A FlutterFlow app without proper access controls is like a building with doors but no locks. Unauthenticated users can often reach screens directly by manipulating deep links. Authenticated users may be able to access other users' data if Firestore rules are missing. Shared devices can expose data if sessions do not expire. This tutorial covers every access control layer in the correct order. The Authentication Gate at the app level handles unauthenticated users. Route protection on page load handles unauthorized navigation. Firestore Security Rules handle unauthorized data access at the database layer. Cloud Function token verification handles API-level access. Inactivity timeout handles shared-device scenarios.

Prerequisites

  • FlutterFlow project with Firebase Authentication enabled
  • At least one protected page (dashboard, settings, or user data screen)
  • Firestore database with user-owned collections
  • Basic familiarity with FlutterFlow Actions and Firestore panel

Step-by-step guide

1

Enable the FlutterFlow Authentication Gate

In FlutterFlow, go to Settings (gear icon, bottom of left sidebar) → App Settings → Authentication. Toggle on Enable Authentication. You will see two drop-downs: Entry Page (the page unauthenticated users land on — typically your Login or Welcome page) and Logged In Page (the page authenticated users see on app start — typically your Home or Dashboard page). FlutterFlow automatically wraps your entire app in an authentication gate that checks Firebase Auth state on every app start. If the user is not signed in, they see the Entry Page. If they are signed in, they skip to Logged In Page. This single setting prevents any unauthenticated user from reaching your app's content pages.

Expected result: Unauthenticated users are redirected to the Login page. Returning authenticated users go directly to the Dashboard without seeing the login screen.

2

Add On Page Load Route Protection for Role-Based Pages

The global Authentication Gate handles unauthenticated users, but authenticated users may still reach pages they should not access — for example, a regular user reaching the Admin Panel via a deep link. For each sensitive page, add an On Page Load action. Select the page in FlutterFlow, open the Action Flow Editor, and add a Conditional action: if currentUser is null OR if the user's role (stored in a Firestore users document) does not equal the required role, then navigate to the appropriate fallback page (Home or Unauthorized). This check runs every time the page loads, including when accessed via deep link or back navigation. For admin pages, query the user's Firestore document in the same On Page Load action and check the role field.

Expected result: Navigating to a protected page via URL or deep link redirects unauthorized users to the home page before the page content appears.

3

Enforce Access Control in Firestore Security Rules

FlutterFlow's route protection blocks navigation, but it does not prevent a malicious user from calling the Firestore API directly to read or write another user's data. Open the Firebase Console, go to Firestore Database, and click the Rules tab. Write rules that check both authentication and document ownership. Every user-owned collection should require request.auth != null (authenticated) and resource.data.userId == request.auth.uid (owns the document). For role-based collections like admin_logs, require request.auth.token.admin == true. Publish the rules. Test them using the Rules Playground by simulating read and write requests as different users.

firestore.rules
1rules_version = '2';
2service cloud.firestore {
3 match /databases/{database}/documents {
4
5 // Only signed-in users can read their own profile
6 match /users/{userId} {
7 allow read, update: if request.auth != null && request.auth.uid == userId;
8 allow create: if request.auth != null && request.auth.uid == userId;
9 allow delete: if false; // Prevent accidental deletion
10 }
11
12 // User-owned data: read/write own documents only
13 match /{collection}/{docId} {
14 allow read: if request.auth != null
15 && resource.data.userId == request.auth.uid;
16 allow create: if request.auth != null
17 && request.resource.data.userId == request.auth.uid;
18 allow update: if request.auth != null
19 && resource.data.userId == request.auth.uid
20 && request.resource.data.userId == request.auth.uid;
21 allow delete: if request.auth != null
22 && resource.data.userId == request.auth.uid;
23 }
24
25 // Admin-only: requires custom claim
26 match /admin_logs/{docId} {
27 allow read, write: if request.auth != null
28 && request.auth.token.admin == true;
29 }
30
31 // Default: deny everything else
32 match /{document=**} {
33 allow read, write: if false;
34 }
35 }
36}

Expected result: Firestore rejects any read or write that does not meet the authentication and ownership rules, regardless of how the request is made.

4

Verify Firebase Tokens in Cloud Functions

Any Cloud Function that accesses sensitive data or performs privileged operations must verify the caller's Firebase Auth token. In callable Cloud Functions (recommended), Firebase automatically verifies the token and exposes it as context.auth. In HTTP functions, you must manually verify using admin.auth().verifyIdToken(). In FlutterFlow, always use callable Cloud Functions (type: onCall) rather than HTTP functions — FlutterFlow's Cloud Function action type handles token passing automatically. Add a check at the top of every callable function: if (!context.auth) throw HttpsError('unauthenticated', 'Login required'). For admin-only functions, additionally check context.auth.token.admin === true.

Expected result: Cloud Functions reject requests from unauthenticated clients and non-admin users attempting admin operations.

5

Implement Inactivity Timeout Sign-Out

On shared devices or kiosk-style deployments, a signed-in session should expire after a period of inactivity. In FlutterFlow, create an App State variable lastActivityTime (DateTime). Add an On Tap action wrapper component that updates lastActivityTime on every user interaction. On each page's On Page Load action, add a check: if DateTime.now() minus lastActivityTime is greater than 15 minutes, call the Firebase Auth Sign Out action and navigate to the Login page. For more robust detection, use a Custom Action with a Timer that fires every minute and checks the inactivity duration. Show a warning dialog at 13 minutes ('You will be signed out in 2 minutes due to inactivity') with a Stay Logged In button that resets lastActivityTime.

Expected result: After 15 minutes with no user interaction, the app shows a warning and then signs out the user, returning them to the Login page.

Complete working example

firestore.rules
1// Complete Firestore Security Rules for a multi-role FlutterFlow app
2// Covers: public pages, user-owned data, admin access, and shared collections
3
4rules_version = '2';
5service cloud.firestore {
6 match /databases/{database}/documents {
7
8 // ---- HELPER FUNCTIONS ----
9 function isSignedIn() {
10 return request.auth != null;
11 }
12 function isOwner(uid) {
13 return isSignedIn() && request.auth.uid == uid;
14 }
15 function ownsDocument() {
16 return isSignedIn() && resource.data.userId == request.auth.uid;
17 }
18 function willOwnDocument() {
19 return isSignedIn() && request.resource.data.userId == request.auth.uid;
20 }
21 function isAdmin() {
22 return isSignedIn() && request.auth.token.admin == true;
23 }
24 function isVerified() {
25 return isSignedIn() && request.auth.token.email_verified == true;
26 }
27
28 // ---- USER PROFILES ----
29 match /users/{userId} {
30 allow read: if isOwner(userId) || isAdmin();
31 allow create: if isOwner(userId);
32 allow update: if isOwner(userId) && !request.resource.data.keys().hasAny(['role', 'isAdmin']);
33 allow delete: if isAdmin();
34 }
35
36 // ---- USER-OWNED COLLECTIONS ----
37 // Pattern applies to: orders, notes, tasks, files, time_entries, etc.
38 match /orders/{docId} {
39 allow read: if ownsDocument() || isAdmin();
40 allow create: if willOwnDocument() && isVerified();
41 allow update: if ownsDocument();
42 allow delete: if ownsDocument() || isAdmin();
43 }
44
45 match /notes/{docId} {
46 allow read, write: if ownsDocument();
47 allow create: if willOwnDocument();
48 }
49
50 // ---- ADMIN-ONLY COLLECTIONS ----
51 match /admin_logs/{docId} {
52 allow read, write: if isAdmin();
53 }
54 match /app_config/{docId} {
55 allow read: if isSignedIn();
56 allow write: if isAdmin();
57 }
58
59 // ---- PUBLIC READ COLLECTIONS ----
60 match /public_content/{docId} {
61 allow read: if true;
62 allow write: if isAdmin();
63 }
64
65 // ---- DENY ALL OTHER ACCESS ----
66 match /{document=**} {
67 allow read, write: if false;
68 }
69 }
70}

Common mistakes when protecting Your FlutterFlow App from Unauthorized Access

Why it's a problem: Protecting routes only in FlutterFlow's Navigator but not in Firestore Security Rules

How to avoid: Always pair UI route protection with matching Firestore Security Rules. Every collection that contains private data must have a rule requiring request.auth.uid to match the document's userId field.

Why it's a problem: Using allow read, write: if request.auth != null as the sole security rule

How to avoid: Add ownership checks: require resource.data.userId == request.auth.uid for reads and updates, and request.resource.data.userId == request.auth.uid for creates.

Why it's a problem: Passing userId as a parameter to a Cloud Function and using it to filter data

How to avoid: Always use context.auth.uid from the verified Firebase token inside Cloud Functions. Ignore any userId field in the request data parameter.

Best practices

  • Enable FlutterFlow's Authentication Gate before building any page that contains private user data.
  • Add role-based On Page Load protection to every admin or privileged page — do not rely on the navigation menu to hide these pages.
  • Write Firestore Security Rules that default to deny and explicitly allow only what is needed.
  • Test Firestore Security Rules using the Firebase Console's Rules Playground with at least three scenarios: unauthenticated, own document, and another user's document.
  • Never trust client-provided user IDs in Cloud Functions — always use context.auth.uid from the verified token.
  • Implement inactivity timeout for apps used in shared environments such as kiosks, school apps, or enterprise tools.
  • Log failed authorization attempts to Firestore (with rate limiting) so you can detect brute-force or enumeration attacks.

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I have a FlutterFlow app with Firebase Authentication and Firestore. I need to protect my admin dashboard page so only users with a role field equal to 'admin' in their Firestore users document can access it. Other authenticated users should be redirected to the home page. How do I implement this in FlutterFlow's On Page Load action, and what Firestore Security Rule should I add to block non-admin users from reading the admin_logs collection?

FlutterFlow Prompt

Add an On Page Load action to my FlutterFlow AdminDashboard page that checks if the current user's Firestore document has a role field equal to 'admin'. If not, navigate to the HomePage. Make sure to wait for the Firestore query to complete before checking the role value.

Frequently asked questions

Does FlutterFlow's Authentication Gate protect every page automatically?

The Authentication Gate protects app launch — unauthenticated users are sent to the Entry Page. However, it does not protect individual pages from authenticated users with incorrect roles. You must add On Page Load route protection to each sensitive page for role-based access control.

Can a user reach a protected page by typing its URL or using a deep link?

Without On Page Load protection, yes. Deep links can bypass FlutterFlow's navigation stack and open any page directly. Always add an On Page Load action to sensitive pages that verifies authorization and redirects unauthorized users.

How do I sign out a user automatically after inactivity?

Store the lastActivityTime in App State and update it on every user interaction. Add a periodic check (every 60 seconds via a Timer action or Custom Action) that signs out the user if DateTime.now() minus lastActivityTime exceeds your timeout threshold (e.g., 15 minutes).

What is the difference between route protection and Firestore Security Rules?

Route protection prevents navigation to pages within the app's UI. Firestore Security Rules prevent data access at the database level — including direct API calls that bypass your app entirely. You need both: route protection for UX, and Security Rules for actual security.

How do I prevent a user from accessing the app while their account is suspended?

Add a status field to your Firestore users document with values like 'active', 'suspended', or 'banned'. In the On Page Load action on the app's main page, check this field after authentication. If the status is not 'active', sign out the user and show a suspension message. Also add a Firestore Security Rule that checks the status field: allow read, write: if resource.data.status == 'active'.

Does FlutterFlow support multi-factor authentication?

Firebase Authentication supports multi-factor authentication (MFA) with SMS OTP and TOTP authenticators. FlutterFlow does not have built-in MFA widgets, but you can implement it using Custom Actions that call the Firebase Auth SDK's MFA APIs directly.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.