I'm trying to set up a GCP Cloud Function to generate the email verification link using admin.auth().generateEmailVerificationLink
, but it throws the error:
Error: Credential implementation provided to initializeApp() via the "credential" property has insufficient permission to access the requested resource. See https://firebase.google.com/docs/admin/setup for details on how to authenticate this SDK with appropriate permissions.
I was able to reproduce this error with the following Cloud Function code:
index.js:
const admin = require('firebase-admin');
admin.initializeApp();
exports.helloWorld = (req, res) => {
execute(res);
};
const execute = async (res) => {
const email = '[email protected]';
const url = 'https://example.firebaseapp.com';
const link = await admin.auth().generateEmailVerificationLink(email, { url });
console.log(link);
res.status(200).send(link);
};
package.json:
{
"name": "sample-http",
"version": "0.0.1",
"dependencies": {
"firebase-admin": "^10.0.2"
}
}
My Firebase Admin Service Account ([email protected]
) has the roles:
- Firebase Admin SDK Administrator Service Agent
- Service Account Token Creator
I also viewed the API Key in Firebase Console, found it in GCP (Browser key (auto created by Firebase)
, and see that it has the following APIs selected:
- Cloud Firestore API
- Cloud Functions API
- Firebase Installations API
- Token Service API
- Identity Toolkit API
I tried following the provided link (https://firebase.google.com/docs/admin/setup), but it seems specific to setting up admin
outside of a GCP Cloud Function (see https://firebase.google.com/docs/admin/setup#initialize-without-parameters). I also read through https://firebase.google.com/docs/auth/admin/email-action-links, but there were no helpful details that I could find.
I tried using functions.https.onCall
instead of the regular GCP exports.
I tried setting FIREBASE_CONFIG={"projectId":"example","storageBucket":"example.appspot.com","locationId":"<my-region>"}
and GCLOUD_PROJECT=example
as runtime env vars.
CodePudding user response:
The issue was that because I was deploying the function on GCP (and not through Firebase), the actual service account that runs the function is not the one specified in the Firebase console ([email protected]
), it is instead the App Engine default service account:
At runtime, Cloud Functions defaults to using the App Engine default service account ([email protected])
Source: https://cloud.google.com/functions/docs/concepts/iam#access_control_for_service_accounts
So in this case, the call worked once I gave my account [email protected]
the roles:
- Firebase Admin SDK Administrator Service Agent
- Service Account Token Creator
As a side note, no additional options were needed for admin.initializeApp()
nor were the Runtime Environment Variables needed.
CodePudding user response:
Since you did not deploy using the Firebase CLI and instead deployed with the Google Cloud Console, the FIREBASE_CONFIG
environment variable was not deployed with it. See note. What you need to do is add a Runtime Variable of something like this:
Key: FIREBASE_CONFIG
Value: {"projectId":"myawesomeproject","storageBucket":"myawesomeproject.appspot.com","locationId":"us-central"}
Key: GCLOUD_PROJECT
value: myawesomeproject
I was able to test this using the Firebase CLI to deploy a function known to work and then compared the function variables and environment settings against a function deployed from the Google Cloud Console.