This error occurs when your Firestore security rules deny access to the requested resource. Fix it by reviewing and updating your security rules to allow authenticated users or by ensuring the user is properly logged in before accessing the database.
The Firebase Firestore "Missing or insufficient permissions" error is thrown when the server rejects a client request because the user does not have permission to access the requested resource. This happens when your Firestore security rules do not permit the operation for the current user's authentication state or role. Security rules in Firestore act as a gatekeeper between your client application and the database. They determine who can read, write, or delete documents. When a rule condition evaluates to false, the entire request is denied with this permission error. Unlike filters, security rules are all-or-nothingβif a query could return any documents the user doesn't have permission to read, the entire query fails.
Verify that the user is properly signed in before attempting Firestore operations. Firebase throws permission denied when an unauthenticated user tries to access protected resources.
import { getAuth } from "firebase/auth";
const auth = getAuth();
if (auth.currentUser) {
console.log("User is logged in:", auth.currentUser.email);
} else {
console.log("User is not authenticated");
// Call sign in function before accessing Firestore
}Navigate to the Firebase Console, select your project, go to Firestore Database, and click the "Rules" tab. Review your current security rules to understand what permissions are allowed.
The most basic authenticated-only rule looks like this:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}This rule allows any authenticated user to read and write to any document. Adjust based on your specific requirements.
For better security, create rules for specific collections instead of allowing all documents:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Allow users to read/write their own user document
match /users/{userId} {
allow read, write: if request.auth.uid == userId;
}
// Allow anyone authenticated to read posts
match /posts/{postId} {
allow read: if request.auth != null;
allow create: if request.auth != null;
allow update, delete: if request.auth.uid == resource.data.authorId;
}
}
}Replace "users" and "posts" with your actual collection names and adjust conditions based on your app's logic.
Click the "Publish" button in the Rules tab to save your changes. After publishing, wait up to 1 minute for the rules to take effect for new requests, and up to 10 minutes for all active listeners to update.
In the Firebase Console, you can use the "Rules Playground" to test your rules without affecting the live database. Click "Rules Playground" in the Rules tab, then simulate different user authentication states and test specific document paths.
Remember that security rules only apply to client-side access (web and mobile apps). If you're using Firebase Admin SDK on a backend server, security rules are bypassed entirely:
// Client-side (subject to security rules)
import { getFirestore, collection, query, where, getDocs } from "firebase/firestore";
const db = getFirestore();
const q = query(collection(db, "users"), where("active", "==", true));
const snapshot = await getDocs(q);
// Server-side (bypasses security rules)
import admin from "firebase-admin";
const db = admin.firestore();
const snapshot = await db.collection("users").where("active", "==", true).get();Use Admin SDK for backend operations and the regular Firebase SDK for client code.
If you're getting permission denied when reading a document immediately after writing it, you may be hitting a race condition. Wait for the write operation to complete before reading:
import { getFirestore, collection, addDoc, getDoc, doc } from "firebase/firestore";
const db = getFirestore();
try {
// Write document
const docRef = await addDoc(collection(db, "users"), { name: "John" });
// Wait for write to complete, then read
const docSnap = await getDoc(doc(db, "users", docRef.id));
if (docSnap.exists()) {
console.log("Document:", docSnap.data());
}
} catch (error) {
console.error("Error:", error.message);
}Collection group queries require specific rule syntax. If you're using collectionGroup() queries, ensure your rules explicitly allow them:
match /{path=**}/comments/{comment} {
allow read: if request.auth != null;
}If your test rules have expired (they expire after 30 days), you'll see "allow read, write: if false" in the Rules tab. Update them immediately.
When using Firebase with Next.js or backend frameworks, always use Admin SDK there and the regular SDK in client components. For App Router, use "use client" directives with the client SDK.
messaging/UNSPECIFIED_ERROR: No additional information available
How to fix "messaging/UNSPECIFIED_ERROR: No additional information available" in Firebase Cloud Messaging
App Check: reCAPTCHA Score Too Low
App Check reCAPTCHA Score Too Low
storage/invalid-url: Invalid URL format for Cloud Storage reference
How to fix invalid URL format in Firebase Cloud Storage
auth/missing-uid: User ID identifier required
How to fix "auth/missing-uid: User ID identifier required" in Firebase
auth/invalid-argument: Invalid parameter passed to method
How to fix "auth/invalid-argument: Invalid parameter passed to method" in Firebase