I've got the following code for a an API endpoint that is supposed to trigger a Firestore backup using firebase-admin.
This is how I'm initializing firebase-admin;
import * as admin from "firebase-admin";
admin.initializeApp({
credential: admin.credential.cert(
SERVICE_ACCOUNT as admin.ServiceAccount
)});
The service account key is a JSON I've downloaded using the default firebase-admin service account:
This is the backup.ts API request handler.
export const backupData: RequestHandler = async (req, res) => {
try {
const PROJECT_ID = process.env.PROJECT_ID;
const client = new admin.firestore.v1.FirestoreAdminClient();
const DB_NAME = client.databasePath(PROJECT_ID, "(default)");
const BUCKET = `gs://${PROJECT_ID}.appspot.com`;
const FOLDER = `firestore-backup`;
const FULL_PATH = `${BUCKET}/${FOLDER}`;
const responses = await client.exportDocuments({
name: DB_NAME,
outputUriPrefix: FULL_PATH,
collectionIds: [] // CAN LIST SPECIFIC COLLECTIONS
});
const response = responses[0];
return res.sendStatus(200);
} else
return res.sendStatus(403);
}
catch(err) {
console.error(err.message || DEFAULT_ERROR_MSG);
return res.sendStatus(500);
}
};
The weird thing is:
It works perfectly on my dev environment. I mean, I run my local server and hit localhost:8080/api/backup (which is the correct endpoint) and everything works correctly and the backup is triggered.
But after I deploy it to my cloud run service, it no longer works.
This is the error I'm getting on my cloud run service:
7 PERMISSION_DENIED: The caller does not have permission
Do I need to add more permissions to that service account? But why does it work with that very same service account on my local dev environment? Should I not use a service account when I'm initializing it on my cloud run service? Don't know what to do here.
UPDATE 1:
I've just tried to initialize it like this, but got the same results:
admin.initializeApp({
credential: admin.credential.cert(SERVICE_ACCOUNT),
databaseURL: `https://${PROJECT_ID}.firebaseio.com`,
storageBucket: `${PROJECT_ID}.appspot.com`
});
Also, just followed this doc tutorial and added these roles both to my firebase-admin and [email protected]. Still not working:
Cloud Datastore Import Export AdminStorage Admin
UPDATE 2:
Following this doc, I've just tried to initialize the firebase-admin without any parameters. Still same result:
admin.initializeApp();
UPDATE 3:
Following the previous docs and this doc, I've added the IAM roles of Cloud Datastore Import Export Admin and Storage Admin to my [email protected] service account. Still same results.
CONCLUSION
It just worked. But I've done so many attempts that I'm not really sure of what made it work. I'm guessing it was what I did on UPDATE 3. Will check that out and answer tomorrow.




storage bucket list,Cloud Datastore Import Export Admin,Cloud Datastore User. A collection-based backup is done daily. I see you have it working. Perhaps at this point setup a new service account to try and get least privileges set. - Brettski