Google Cloud Function: Could not load the default credentials

firebasegoogle-cloud-platform

I noticed error in my Cloud Function invocation via Pub/Sub.
Every time it throws an Error :

Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
    at GoogleAuth.getApplicationDefaultAsync (/srv/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:161:19)
    at process._tickCallback (internal/process/next_tick.js:68:7)

I already redeployed it with specific credentials for use.
And refactored my code accordingly to that proposal
https://stackoverflow.com/questions/58127896/error-could-not-load-the-default-credentials-firebase-function-to-firestore/58779000#58779000

But nothing has been changed. It looks like Google released some updates and it was crashed. I think so because of our mobile app, wich does use Firebase SDK and invokes cloud functions directly. But it's wrote on Swift but my Cloud Functions is wrote on JS. So it means that we are using DIFFERENT libs, but have THE SAME ISSUE.
Does somebody know something about that issue ? It would be super helpful for my team.
Thanks in advance.

Best Answer

As mentioned in the github issue

creating a client in the global scope outside of your function will solve this issue see: function execution lifetime.

If your code looks like this:

const {CloudTasksClient} = require('@google-cloud/task');
// CloudTasksClient, could be Storage, or Vision, or Speech.
const task = new CloudTasksClient();
export.helloWorld = (req, res) => {
  res.send('hello world');
}

Instead write:

const {CloudTasksClient} = require('@google-cloud/task');
// CloudTasksClient, could be Storage, or Vision, or Speech.
let task;
export.helloWorld = async (req, res) => {
  if (!task) {
    task = new CloudTasksClient();
  }
  await task.doSomething(); // or storage.doSomething(), etc.
  res.send('hello world');
}

There is work in motion to shield folks from this issue. But, as described in the execution timeline, the core of the problem is that asynchronous work cannot happen outside of the request cycle of your function.

This may also fix the problem

You can set an environment variable on a cloud function when deployed using the firebase-tools CL

  • Set the env variable DEBUG_AUTH to true

  • Run

    npm install --save @google-cloud/firestore@latest gcp-metadata@latest

There are two ways to do this:

1.The official (old) way is to set the variable using gcloud or pantheon. The CLI will respect the variable on future deploys.

2.You can opt into the not-yet-public support for managing env variables with dot-env files. This can be done by calling:

firebase --open-sesame dotenv
#From their functions directory    
echo "DEBUG_AUTH=true" > .env  
firebase deploy --only functions
Related Topic