6

I am currently following this tutorial on youtube and at around the 26 minutes mark, the author is running his functions locally with the firebase serve command.

This works fine for him, but as soon as I try to do that, I get the next error:

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

Now, the error is giving me a link which helps me to solve this error, by setting an environment variable in my windows (which I don't like, because will this and how will this gonna work when I develop in different projects linked to different gmail accounts?)

Another solution I found, but not tested yet, is authenticate locally with a gcloud command gcloud auth application-default login.

None of these steps is done by the author in the tutorial.

I searched in the comments of the video and someone mentioned that it has to do with the firebase-tools versions. His solution was to go back to firebase-tools version 6.8.0 while the current latest is 7.2.2.

So I wonder, what has changed that firebase serve with firebase-tools 7.2.2 isn't able to run a cloud function anymore when the cloud function tries to store something in a remote firestore database while this was working with firebase-tools 6.8.0?

And will it ever gonna work with version 7.2.2 or higher like it did with version 6.8.0?

benomatis
  • 5,536
  • 7
  • 36
  • 59
Cornelis
  • 1,729
  • 5
  • 23
  • 39
  • Seems [this](https://stackoverflow.com/questions/58127896/error-could-not-load-the-default-credentials-firebase-function-to-firestore) is a congruent case. May I ask if you alredy solved it? – Philipp Oct 27 '19 at 21:12
  • @Philipp see my answer, I hope it'll help you out! – aldobaie Nov 13 '19 at 12:17

4 Answers4

1

For anyone having this problem, you can see my answer here

The problem is with the unhandled promises. Functions terminate once done and don't wait for the callbacks, and Firebase Cloud Functions don't allow access to the processor after it terminates.

aldobaie
  • 1,387
  • 10
  • 15
1

I ran into the same issue. If you want to post data, the tutorial's code works. But if you want to retrieve data from database then you have to change few lines of your code.

Tutorial Author's Code:

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

app.get('/screams', (req, res) => {
    admin
    .firestore()
    .collection('screams')
    .get()
    .then(data => {
        const screams = [];
        data.map(doc => {
        screams.push({
            screamdId : doc.id,
            content : doc.data().content,
            createdAt : doc.data().createdAt,
            username : doc.data().username,
            likeCount : doc.data().likeCount,
            commentCount : doc.data().commentCount
        });
    });
    res.json({message : "Screams displayed successfully", data : screams});
    })
    .catch(err => {});
});

exports.api = functions.https.onRequest(app);

After Changes:

const functions = require('firebase-functions');
const express = require('express');
const app = express();
const admin = require('firebase-admin');
const serviceAccount = require('../path/to/privKey.js');
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'https://project-name.firebaseio.com'
});


app.get('/screams', (req, res) => {
    console.log("I am here");
    admin.firestore()
    .collection('screams')
    .get()
    .then(data => {
        const screams = [];

        data.docs.map(doc => {
        screams.push({
            screamdId : doc.id,
            content : doc.data().content,
            createdAt : doc.data().createdAt,
            username : doc.data().username,
            likeCount : doc.data().likeCount,
            commentCount : doc.data().commentCount
        });
    });
    res.json({message : "Screams displayed successfully", data : screams});
    })
    .catch(err => {
        res.status(500).json({message : "Some Error occured"});
    });
});

exports.api = functions.https.onRequest(app);

Please Note: get().then(data => {}) "data" will not return you an array of collection docs. You have to do call data.docs.map(doc => {}). Else it will say "data.map() is not a function".

tobsob
  • 602
  • 9
  • 22
0

Use firebase login instead ... see the CLI reference

(one can deploy them with firebase and with gcloud).

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • when creating a new project (firebase init) a login needs to be done as well before the init step so a project can be selected. So I am already logged in. But to be certain, I updated the firebase tools to 7.2.2 (no new version yet so this one is 18 days old) and I did a firebase login as you suggested. I got a message back saying I am already logged in. So I did a firebase serve and surprisingly it is working now, which I wouldn't expect. I don't understand it either as login only showed me the message, no login procedure was launched. So far, it looks like magic to me now. – Cornelis Aug 17 '19 at 12:34
0

Consider setting the environment variable to provide the needed credentials.

Setting the environment variable allows you to provide credentials separately from your application, without making changes to application code when you deploy.

It is not said that the environment variable is permanent so you will be able to overwrite or change them after this.

Kevin Quinzel
  • 1,430
  • 1
  • 13
  • 23
  • True, but what if you work on 2 or more different projects simultaneously, using 2 different gmail accounts? Do you need to change the environment variable value all the time or is there another handy trick to avoid this. – Cornelis Aug 17 '19 at 12:28
  • The Environment variable path is used only for your current terminal session. If you need to access to different projects, you can set service account(s) to access to your projects. You can have one service account for both projects or one service account for each project. – Kevin Quinzel Aug 26 '19 at 16:07