Dhara
Dhara

Reputation: 1481

"PERMISSION_DENIED: Missing or insufficient permissions" when firestore function called using google cloud task

I have created one function which adds an entry to the Firestore database.

const functions = require("firebase-functions");

const admin = require('firebase-admin');
admin.initializeApp();

exports.addMessage = functions.https.onRequest(async (req, res) => {
    const original = 'dhara';
    const writeResult = await admin.firestore().collection('messages').add({original: original});
    res.json({result: `Message with ID: ${writeResult.id} added.`});
});

Created queue by following command

gcloud tasks queues create auction-autobid-queue

Then created Google Cloud Task.

const serviceAccount = require('./my-service-account.json');

const {CloudTasksClient} = require('@google-cloud/tasks');

const client = new CloudTasksClient({
  credentials: serviceAccount
});

async function createTask() {
     const project = 'my-project';
     const queue = 'auction-autobid-queue';
     const location = 'europe-west1';
     const payload = 'Hello, World!';
     const serviceAccountEmail = "[email protected]";
      const parent = client.queuePath(project, location, queue);
  
    const task = {
      httpRequest: {
        httpMethod: 'GET',
        url: 'https://us-central1-my-project.cloudfunctions.net/addMessage',
        oidcToken: {
          serviceAccountEmail,
        },
      },
    };
  
    const inSeconds = 60;
    if (inSeconds) {
     task.scheduleTime = {
        seconds: inSeconds + Date.now() / 1000
      };
    }
  
    console.log('Sending task:');
    console.log(task);
    const request = {parent, task};
    const [response] = await client.createTask(request);
    const name = response.name;
    console.log(`Created task ${name}`);
  }

  process.on('unhandledRejection', err => {
    console.error(err.message);
    process.exitCode = 1;
  });

  createTask();

I added this task to an queue. Now when I run this task from the Google Cloud Console, it throws error. I checked in firebase functions log and I can see function called but it throws me

Error: 7 PERMISSION_DENIED: Missing or insufficient permissions.

enter image description here

I have a service account which has Cloud Functions Developer Cloud Functions Service Agent Owner Roles.

I can't get what is the issue here as assigned roles are pretty good.

Upvotes: 2

Views: 6423

Answers (2)

Dhara
Dhara

Reputation: 1481

Finally, I found the answer after lots of struggle,

There was a default service account "App Engine default service account" is assigned to the function. It is not using my service account

So I checked if IAM has that service account is added as a member or not for the project. For my case, there was not added so I added the default service account to the project then assigned the Owner role. But by assigning only the owner role it was not working so I added two other roles Cloud Functions Admin, Cloud Tasks Admin. After this, my function saved data to the database.

Hope this will help to others.

Upvotes: 4

Towfique Ahmed
Towfique Ahmed

Reputation: 21

Your firestore database may not linked properly because you didn't initialize it with the serviceAccountKey.

Find your serviceAccountKey on: Firebase dashboard -> Project Settings -> Service Accounts tab

Download that json file, rename it and copy it to your source folder, in my case I renamed it as "myServiceKey.json"

const admin = require("firebase-admin");
const serviceAccount = require("./myServiceKey.json");

const firebase = admin.initializeApp({
   credential: admin.credential.cert(serviceAccount)
});
const firestore = firebase.firestore();

exports.addMessage = functions.https.onRequest(async (req, res) => {
    const original = 'dhara';
    const writeResult = await firestore().collection('messages').add({original: original});
    res.json({result: `Message with ID: ${writeResult.id} added.`});
});

Upvotes: 2

Related Questions