Error: Could not load the default credentials (Firebase function to firestore)

百般思念 提交于 2019-12-17 19:13:50

问题


I am attempting to write an onCall function for Firebase Cloud Functions that performs advanced querying tasks on a firestore database (i.e. checking a text query up against AutoML natural lang to get a category, etc) but I keep running into a problem trying to query the database from the function:

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

Function:

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

exports.query = functions.https.onCall((data, context) => {
    const text = data.text;
    var results = [];
    const promise = db.collection('providers').get()
    promise.then((snapshot) => {
        console.log('marker');
        snapshot.forEach((doc) => {
            results.push({id: doc.id, data: doc.data()});
        });
        console.log('yessir');
        return {results: results};
    }).catch((err) => {
        console.log('Error getting documents :: ', err)
        console.log('nosir');
        return {results: "no results"};
    });
});

Longer output:

Function execution started
Function execution took 8ms, finished with status code: 200
Error getting documents :: (etc, same error)
nosir

Example 2 (no change in running):

Function execution started
Function execution took 1200 ms, finished with status code: 200
marker
yessir

I can't figure out where this problem is coming from or how to resolve it. Any help?

Regards.


回答1:


I had the same error "Could not load the default credentials".

The error occured after updating my project dependencies with npm update. More precisely firebase-admin and firebase-functions.

Before update:

"dependencies": {
    "@google-cloud/firestore": "^1.3.0",
    "firebase-admin": "~7.0.0",
    "firebase-functions": "^2.2.0"
}

After update:

"dependencies": {
    "@google-cloud/firestore": "^1.3.0",
    "firebase-admin": "^8.6.0",
    "firebase-functions": "^3.3.0"
}

I added the serviceAccountKey.json to my project and changed the imports with the code provided at the service account setting of my firebase project.

From :

var admin = require('firebase-admin')

admin.initializeApp()

To:

var admin = require('firebase-admin');    
var serviceAccount = require('path/to/serviceAccountKey.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'https://my-project.firebaseio.com'
});

See @Fernando Rocha's answer below to access the account setting of your firebase project.




回答2:


What I did to solve it was add my firebase admin sdk key to my project.

I downloaded it at

https://console.firebase.google.com/u/0/project/YOUR_PROJECT_ID/settings/serviceaccounts/adminsdk

then at admin.initializeApp(); I changed to:

admin.initializeApp({
    credential: admin.credential.cert(require('../keys/admin.json'))
});

My folder structure is

├── key
│   ├── admin.json
├── src
│   ├── index.ts



回答3:


@aldobaie's answer helped me figure out what was going on for my use case. For those who are not looking to add async/await to all their calls, remember that the firestore calls return promises, so prepending them with return has the same effect.

In my case:

function doSomething(...) {
    return admin.firestore().collection(...).doc(...).get()
        .then((doc) => {...})
        .catch(err => {...})
}

module.exports = functions.firestore.document('collection/{docId}').onWrite((change, context) => {
    return doSomething()
})

I think the accepted answer goes against Firebase's recommend configuration. The function environment has access to admin credentials already, and passing your key in the code is not recommended.

I do it like this:

const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp(functions.config().firebase)



回答4:


I ran into the same problem myself. Sometimes the function works and many times it would through the Error: Could not load the default credentials error. The problem I believe have been solved by watching for the Callbacks. You have to keep the function running until the callbacks have been called using the await and async prefixes.

Firebase Cloud Functions don't allow the access to the processor through callbacks once it's been terminated! That's why we get the Error: Could not load the default credentials error.

So, whenever you have a .then() function prefix it with await and prefix the function it's inside it with async and prefix any call to the function with await.

async function registerUser(..) {
    ...
    await admin.firestore().collection(..)...
    ...
}

I hope this helps you out!




回答5:


Another option is to set the service account key in an environmental variable instead of setting it with a call to firebaseAdmin.initializeApp({ credential }).

Linux

export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json"

Windows PowerShell

$env:GOOGLE_APPLICATION_CREDENTIALS="[PATH]"
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\[FILE_NAME].json"

Postscript: An even better option might be to use the local emulator suite.




回答6:


I do not want to use @Fernando solution even though there is nothing wrong.

I have prd and non-prd environment. I use firebase use command to push the changes to the correct environment. When I deploy, firebase uses the default service account. Also I do not want to have the keys in the project folder or in my git repo.

The way I solved might not work for others, but want to share here.

The issue came to me when I updated the permission of the firebase project to give a viewer with editor permission. I made that person the owner and rolled back to editor. It went away. It is not justifying as a fix, but worked for me and I do not have to download the key.



来源:https://stackoverflow.com/questions/58127896/error-could-not-load-the-default-credentials-firebase-function-to-firestore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!