All guidesMore providers: databases, auth, hosting, email and payments
On this page

Firestore error

Firebase

FirebaseError: Missing or insufficient permissions.

By Ohad Krispin, founder of VibeRaven · LinkedIn

"FirebaseError: Missing or insufficient permissions." means Firestore checked a request from the client SDK against your Security Rules and no rule allowed it. The SDK reports it with the code permission-denied; the text itself is not in the firebase 13.1.0 code we searched. Three causes cover most cases: a rule needs request.auth != null and the query ran before sign-in finished, the rules published in the Firebase project are not the ones you edited, or the query could return documents the rules do not allow, because rules are not filters. The Admin SDK bypasses rules, so the same read can work in a route handler. Fix the cause, publish the rules, and run the query again as the same user.

Does it only fail on the first page load, before the user is signed in?

Firebase Auth restores the session asynchronously. The Firebase docs say the recommended way to get the current user is an observer on the Auth object, and that currentUser might be null because the auth object has not finished initializing. A rule such as allow read, write: if request.auth != null denies a query sent in that moment. A thread in the firebase-js-sdk repository suspects this timing for the same error; the poster did not confirm it. Start the query from the observer.

import { onAuthStateChanged } from 'firebase/auth'

onAuthStateChanged(auth, (user) => {
  if (user) loadNotes(user.uid)
})

Why does the query fail when the signed-in user owns every document?

The Firebase docs say rules are not filters: if a query could return documents the client has no permission to read, the entire request fails. With a rule that compares request.auth.uid to resource.data.author, reading the whole collection fails even when the current user wrote every document, because the rules check what the query could return. The query has to carry the same condition as the rule.

// rule: allow read: if request.auth != null && request.auth.uid == resource.data.author;

// denied: the query could return other users' documents
getDocs(collection(db, 'stories'))

// allowed: the query is limited to the signed-in user
getDocs(query(collection(db, 'stories'), where('author', '==', user.uid)))

Why does the same read work in my API route with the Admin SDK?

The Firestore docs say the server client libraries bypass all Security Rules and authenticate with Google Application Default Credentials. A read that works through the Admin SDK and fails in the browser therefore points at the rules, not at the data. It also means a route handler that uses the Admin SDK must check the signed-in user itself.

Checklist

How to fix it, then check the fix

  1. 01
    Find the failing call and the collection path it reads or writes:
    grep -rnE "getDocs|getDoc|onSnapshot|addDoc|setDoc|updateDoc|deleteDoc" --exclude-dir=node_modules --exclude-dir=.next .
  2. 02Open the Rules tab of the Firestore database in the Firebase project whose project ID is set for that Vercel environment, and read the rule for that path. A Production and a Preview deployment can point at different projects.
  3. 03
    Deploy the rules file from your repo. The Firebase docs say rules in your project directory overwrite what is in the console, and that an update can take up to a minute to reach new queries:
    firebase deploy --only firestore
  4. 04Run the failing request in the Rules Playground, once as a signed-in user and once as signed out, and change the rule or the query until the signed-in run passes.
  5. 05Pin the fix with a rules test in the Emulator Suite: assertSucceeds as authenticatedContext for the owner, assertFails as unauthenticatedContext. Do not clear the error with allow read, write: if true; the Firebase docs say never to use it in production.

Related

Sources

Official docs behind this checklist

FAQ

FAQ for builders before launch

How long until new rules apply?

The Firebase docs say updates to Cloud Firestore Security Rules can take up to a minute to affect new queries and listeners. Run the query again after that.

Is the message different for a denied write?

The Firebase docs say that if the rules deny any of the document paths in a request, the entire request fails, so a request that names several documents fails as a whole when one path is denied. We did not capture the message text for each case.

Can I just allow everything while I debug?

The Firebase docs show that rule set and say to never use it in production, because it allows anyone to overwrite your entire database. Use the Rules Playground or the emulator to debug instead.