VibeCPR

← All fixes

Firebase · Security rules

Fix "Your Cloud Firestore database has insecure rules" (Firebase email)

Updated · Applies to: Firebase, Firestore, Replit, Bolt, Cursor, FlutterFlow

TL;DR fix: Your Firestore rules allow open access, usually allow read, write: if true or a global match /{document=**} left over from Test mode. Anyone on the internet can read (and maybe write) your whole database. Replace it with per-collection rules: public data gets allow read: if true but no public writes, and user data gets request.auth.uid == userId. Test in the Rules Playground, then publish.

Steps

  1. Open your current rules. Firebase console → Firestore Database → Rules. Look for allow read, write: if true, a time-limited test-mode rule, or match /{document=**}.
  2. List your collections and who should access each. For each collection decide: public read? signed-in users only? only the owner? server only?
  3. Replace the global wildcard with per-collection rules. Write a match block per collection and keep a final deny-by-default. Don't use match /{document=**} with allow read, write.
  4. Restrict writes to owners. Use request.auth.uid == userId for user documents, or compare to a field like request.resource.data.ownerId for created documents.
  5. Test before publishing. Use the Rules Playground (or the emulator) to try reads and writes as a signed-out user, the owner, and a different user.
  6. Publish and confirm the app still works. Publish the rules, then click through your app. Move admin-only operations to Cloud Functions or a server using the Admin SDK.

Replace open rules with this starting point

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Public catalog: anyone can read, nobody writes from the client
    match /products/{productId} {
      allow read: if true;
      allow write: if false;
    }
    // Each user can read and write only their own profile
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
    // Posts: public read, only the author can create/edit
    match /posts/{postId} {
      allow read: if true;
      allow create: if request.auth != null
                    && request.resource.data.authorId == request.auth.uid;
      allow update, delete: if request.auth != null
                    && resource.data.authorId == request.auth.uid;
    }
    // Everything else: denied by default (no match = no access)
  }
}

Firebase’s own guidance: “If you’re not authenticating users and configuring security rules, then anyone who guesses your project ID can steal, modify, or delete the data.” (Firebase docs)

Prompt for your AI tool

Our Firestore rules are "allow read, write: if true". Replace them with per-collection rules:
list every collection the app uses, propose who may read/write each, require request.auth.uid
ownership for user data, deny everything else. No global /{document=**} allow rule. Show rules first.

When to get help

Get help if your data model mixes public and private fields in the same documents, if you have admin roles, or if the database was open long enough that you need to check what was read or changed.

FAQ

What does "Your Cloud Firestore database has insecure rules" mean?

Firebase detected security rules that let any user read or write your entire database, typically allow read, write: if true or an expired test-mode rule. Anyone who knows your project ID, which is public in your app config, can access the data. Replace them with per-collection rules that check request.auth.

Is "allow read, write: if request.auth != null" secure?

It is better than open access but often still too broad: any signed-up user can read and change every document, including other users' data. Firebase's docs warn to confirm you really want any logged-in user to have access, and to narrow it with conditions like request.auth.uid == userId.

My Firebase config (apiKey) is in my frontend. Is that a leak?

No. The Firebase web config including apiKey is meant to be public. Security comes from Security Rules (and App Check), which is why open rules are the real problem.

Sources

Related fixes