The "Caller does not have required role" error occurs when your Firebase project member, service account, or client lacks sufficient IAM permissions or security rule clearance. This is typically resolved by granting the appropriate IAM roles or fixing Firestore security rules.
This error is thrown by Firebase when an authenticated or service account user attempts an operation they lack permissions for. The error has two distinct contexts: (1) Cloud Functions or backend access to Firestore/Realtime Database, where IAM roles control permissions, and (2) Client-side Firestore access, where security rules enforce access control. In both cases, Firebase servers reject the operation because the principal (user, service account, or function) does not have the required permissions to execute that specific operation.
For client-side Firestore access, verify that your user is properly authenticated before attempting database operations:
import { getAuth } from "firebase/auth";
import { getFirestore, doc, getDoc } from "firebase/firestore";
const auth = getAuth();
const currentUser = auth.currentUser;
if (currentUser) {
console.log("User authenticated:", currentUser.uid);
const db = getFirestore();
const docRef = doc(db, "users", currentUser.uid);
const docSnap = await getDoc(docRef);
} else {
console.log("User not authenticated");
// Sign in user first
}If the user is not authenticated, sign them in using Firebase Authentication before accessing Firestore.
Access the Firestore Security Rules in the Firebase Console and ensure they allow the operations your users need. For authenticated users with basic read/write access:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}For user-specific access, use more granular rules:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth.uid == userId;
}
match /public/{document=**} {
allow read: if true;
}
}
}After updating rules, click "Publish" and wait for them to deploy (usually 1-2 minutes).
For Cloud Functions or backend services using the Admin SDK, grant the required IAM roles to the service account in Google Cloud Console:
1. Go to Google Cloud Console > IAM & Admin > IAM
2. Find the service account (usually named "App Engine default service account" with format: [email protected])
3. Click the edit icon and add these roles:
- Cloud Datastore User (roles/datastore.user) - minimum required
- Firebase Admin (roles/firebase.admin) - broader access
Alternatively, use the gcloud CLI:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:[email protected] \
--role=roles/datastore.user
# Or for broader access:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:[email protected] \
--role=roles/firebase.adminAfter granting roles, it takes up to 5 minutes for the permissions to take effect due to IAM caching.
Ensure the necessary APIs are enabled in your Google Cloud project:
1. Go to Google Cloud Console > APIs & Services > Library
2. Search for and enable:
- Cloud Firestore API
- Cloud Functions API (if using functions)
- Service Usage API
Using the gcloud CLI:
gcloud services enable firestore.googleapis.com
gcloud services enable cloudfunctions.googleapis.com
gcloud services enable serviceusage.googleapis.comMissing enabled APIs will cause permission errors even with correct IAM roles.
Before deploying security rule changes to production, test them in the Firebase Console:
1. In Firebase Console, go to Firestore Database > Rules
2. Click the Rules Playground button (or tab)
3. Enter test values:
- Authentication: Mock the auth object (set uid, email, or custom claims)
- Request path: The document path being accessed (e.g., /users/user123)
- Request method: Read, Write, or Delete
4. Click Run to see if the rule allows or denies the request
5. Iterate on rules until tests pass
6. Click Publish to deploy
This prevents deploying broken rules to production.
If using a custom service account (not App Engine default), verify credentials are correct:
1. Go to Google Cloud Console > Service Accounts
2. Select your service account and click Keys
3. If the key is old or expired, create a new one:
- Click Add Key > Create new key > JSON
- Download and store securely
4. In your backend code, initialize the Admin SDK:
import admin from 'firebase-admin';
const serviceAccount = require('./path/to/serviceAccountKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://YOUR_PROJECT.firebaseio.com',
});
const db = admin.firestore();
// Now you can access Firestore without permission issuesThe Admin SDK bypasses security rules entirely, so if you still get permission errors with Admin SDK, it indicates an IAM role problem, not a security rules problem.
Admin SDK Bypass: When using Firebase Admin SDK from a backend (Node.js, Python, etc.), security rules are bypassed entirely. If you still encounter permission errors with Admin SDK, the issue is IAM permissions, not security rules.
Permission Caching: Cloud Firestore caches IAM permissions for 5 minutes. After updating IAM roles, allow up to 5 minutes for changes to take effect.
firebaserules.system Service Account: Firebase automatically manages a special service account ([email protected]) that evaluates security rules. Do not remove the roles/firebaserules.system role from this service account, or all security rules will be denied.
Custom IAM Roles: For fine-grained access control, create custom IAM roles with specific permissions like firestore.databases.get, firestore.documents.list, etc.
Testing with Emulator: Use the Cloud Firestore emulator locally to test security rules and IAM policies before deploying:
firebase emulators:start --only firestoreThis allows rapid iteration without affecting production.
Callable Functions: INTERNAL - Unhandled exception
How to fix "Callable Functions: INTERNAL - Unhandled exception" in Firebase
auth/invalid-hash-algorithm: Hash algorithm doesn't match supported options
How to fix "auth/invalid-hash-algorithm: Hash algorithm doesn't match supported options" in Firebase
Hosting: CORS configuration not set up properly
How to fix CORS configuration in Firebase Hosting
auth/reserved-claims: Custom claims use reserved OIDC claim names
How to fix "reserved claims" error when setting custom claims in Firebase
Callable Functions: UNAUTHENTICATED - Invalid credentials
How to fix "UNAUTHENTICATED - Invalid credentials" in Firebase Callable Functions