What this means
Every request from a web or mobile client to Cloud Firestore is checked against your security rules. If no allow statement matches, the request is denied and the SDK throws 'FirebaseError: Missing or insufficient permissions'. The fix is to add a rule for that path and user, or to change the request so it fits the rules you already have.
Why it happens
- The database was created in production (locked) mode, which denies all client reads and writes, and no rules were added afterwards.
- The request runs before sign-in has finished, so request.auth is null. Generated code often queries on page load without waiting for the auth state.
- The rules cover a different path from the one the code uses. A match on /users/{userId} does not cover a subcollection unless you add one or use a recursive wildcard.
- The query is broader than the rule. Firestore rules are not filters: if a query could return documents the user may not read, the whole query fails, even if every document that exists belongs to them.
- The rules were edited in the console but never published, or a local firestore.rules file was never deployed.
How to fix it
- 1Find the exact path and operation that failed. The browser console stack trace points to the call.
- 2Open Firestore, Rules in the Firebase console and check whether any match block covers that path.
- 3Write a rule that ties access to the signed-in user. Storing user data under a path that contains their uid keeps rules simple.
- 4Make queries match the rule. If the rule says users read only documents where ownerId equals their uid, the query must include where('ownerId', '==', uid).
- 5Wait for authentication before querying, using onAuthStateChanged.
- 6Publish the rules, or run firebase deploy --only firestore:rules.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId}/{document=**} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
match /projects/{projectId} {
allow read, update, delete: if request.auth != null
&& resource.data.ownerId == request.auth.uid;
allow create: if request.auth != null
&& request.resource.data.ownerId == request.auth.uid;
}
}
}How to confirm the fix
- In the Firebase console, open the Rules Playground. Simulate a get on one of your documents as an authenticated user with the owner's uid: it should be allowed. Repeat with a different uid and with authentication off: both should be denied.
- In your own app, sign in as a second test account and try to open the first account's data by changing the id in the URL or request. You should see the permission error.
- For repeatable checks, run rules unit tests against the Firebase Local Emulator Suite.
Frequently asked questions
Why does my query fail when I own every document in the collection?
Firestore evaluates the query against what it could return, not what it does return. Add the same condition to the query that the rule checks, such as where('ownerId', '==', uid).
Do security rules apply to my server code?
No. The server client libraries and Admin SDK bypass security rules and are governed by IAM instead. Rules protect access from web and mobile clients.
I see this error in Cloud Storage or Realtime Database too. Is the fix the same?
The idea is the same, but each product has its own rules file. Check the rules for the product named in the error.