The functions/permission-denied error occurs when your Cloud Function lacks IAM permissions to access other Firebase services. This is typically caused by missing or insufficient Cloud IAM roles assigned to the service account running your function.
Firebase Cloud Functions run as a service account with specific IAM roles. When your function tries to access Firestore, Realtime Database, or other Google Cloud services, Firebase checks if that service account has permission. If the required roles are not assigned, the function is denied access and throws a permission-denied error. This differs from Firestore/Database security rules, which only apply to client-side access—backend servers using the Admin SDK bypass security rules entirely. Your function fails at the IAM level, not the database rules level.
Navigate to the Google Cloud Console and open the Cloud Functions section. Find your function and note which service account it uses (usually displayed as "Runtime service account"). Most functions use the default App Engine service account or a custom service account.
If you don't see this information, go to Cloud Run services and select your function to view the service account in the Security tab.
In the Google Cloud Console, navigate to IAM & Admin > IAM. This is where you manage permissions for all service accounts in your project.
In the IAM permissions page, locate your function's service account (e.g., "service-{PROJECT_ID}@appspot.gserviceaccount.com" or your custom service account). Click the pencil/edit icon on the right side of its row.
Depending on what your function accesses, assign these roles:
For Firestore access:
- Add "Cloud Datastore User" (roles/datastore.user) - minimum required
- Or add "Firebase Admin" (roles/firebase.admin) - broader access to all Firebase services
For custom token generation:
- Add "Service Account Token Creator" (roles/iam.serviceAccountTokenCreator)
For invoking the function from client code:
- Add "Cloud Functions Invoker" (roles/cloudfunctions.functions.invokeSecurityTestResults.invoke)
Click "Add another role" to add multiple roles. Then save your changes.
Wait a few seconds for IAM changes to propagate (usually 5-30 seconds). Then trigger your Cloud Function again. If the issue was permissions, the function should now execute successfully. If using the Firebase Emulator, restart it to ensure it picks up the updated permissions.
Go to Cloud Logging (Cloud Logs) and filter by your function name. Check the logs to confirm the function executed without permission errors. Look for successful execution messages or any remaining errors that indicate different issues.
Security rules vs. IAM: If you're using the Firebase Admin SDK (server-side), security rules in Firestore and Realtime Database are bypassed entirely—your function permission issues are always IAM-related, not rule-related. The permission-denied error comes from Google Cloud IAM, not your database security rules. If using the client SDK from within a function, you'll hit both IAM and security rule checks. Custom roles can be created with minimal permissions instead of using predefined roles if you need fine-grained access control. Firebase Extensions automatically create service accounts with limited permissions; permission errors with extensions usually indicate the extension needs additional roles not granted during installation. For CI/CD pipelines deploying functions, ensure your deployment service account has "Cloud Functions Developer" or "Cloud Functions Admin" roles.
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