firebasegoogle-cloud-platformgoogle-cloud-functionsgoogle-cloud-tasksfirebase-extensions

How to solve lacks IAM permission when backfill data in Firebase extension?


I'm trying to create a simple Firebase extension. I have a few Cloud functions that work fine and I also enabled the option to backfill existing users. This means that when someone installs the extension, I will add a ranking (number) in the Realtime Database.

This is what I have tried. In my extension.yaml file, I have added:

  - name: backfillDocs
    type: firebaseextensions.v1beta.function
    description: >-
      Rank users
    properties:
      runtime: "nodejs16"
      taskQueueTrigger: {}

And I want to do that on install:

lifecycleEvents:
  onInstall:
    function: backfillDocs
    processingMessage: Setting the rank.

I checked the docs, and here is what I have tried with my function:

exports.backfillDocs = tasks
    .taskQueue()
    .onDispatch(async (data) => {
      const offset = data["offset"] !== undefined ? data["offset"] : 0;

      const snapshot = await getFirestore()
          .collection("users")
          .limit(DOCS_PER_BACKFILL)
          .get();

      const processed = await Promise.allSettled(
          snapshot.docs.map(async (doc) => {
            const ref = getDatabase().ref().child("rankings").child(doc.id);
            await ref.set(0);
          }),
      );

      if (processed.length == DOCS_PER_BACKFILL) {
        const queue = getFunctions().taskQueue(
            "backfilldata",
            process.env.EXT_INSTANCE_ID,
        );
        return await queue.enqueue({
          offset: offset + DOCS_PER_BACKFILL,
        });
      } else {
        return getExtensions().runtime()
            .setProcessingState(
                "PROCESSING_COMPLETE",
                "Backfill complete.",
            );
      }
    });

The problem is that, each time I install the extension, I get:

Error: The principal (user or service account) lacks IAM permission "cloudtasks.tasks.create"

I don't see why I get this error since I have enabled Cloud Tasks Enqueuer to project-id@appspot.gserviceaccount.com, firebase-adminsdk-*****@project-id.iam.gserviceaccount.com and firebase-service-account@firebase-sa-management.iam.gserviceaccount.com. Here is a screenshot:

enter image description here

What am I missing? Please help.


Solution

  • The queue name in the code must match the function name. It appears your function is called doBackfillExistingDocuments so when getting the queue ref you need to use the same name:

    exports.doBackfillExistingDocuments = tasks
        .taskQueue()
        .onDispatch(async (data) => {
            // ...
            const queue = getFunctions().taskQueue(
                "doBackfillExistingDocuments", // <----
                process.env.EXT_INSTANCE_ID,
            );
            // ...
         });