Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't latest firebase serve load the default credentials anymore

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?

like image 512
Cornelis Avatar asked Aug 16 '19 13:08

Cornelis


2 Answers

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.

like image 140
aldobaie Avatar answered Nov 03 '22 03:11

aldobaie


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".

like image 35
nisha jakhar Avatar answered Nov 03 '22 01:11

nisha jakhar