firebase-tools: "Error: The incoming JSON object does not contain a client_email field" after upgrading to 7.0.2

[REQUIRED] Environment info

firebase-tools: 7.0.2

Platform: Oracle Linux Server 7.6, Node 10.15

[REQUIRED] Test case

emulate https function with “firebase-admin”: “^8.2.0”, “firebase-functions”: “^3.0.2”

[REQUIRED] Steps to reproduce

run any https function with firebase functions:shell

[REQUIRED] Expected behavior

no error (firebase-tools 7.0.0 throws no error)

[REQUIRED] Actual behavior

Sent request to function.

firebase > ⚠  Error: The incoming JSON object does not contain a client_email field
    at JWT.fromJSON (/riderequest/functions/node_modules/google-auth-library/build/src/auth/jwtclient.js:165:19)
    at GoogleAuth.fromJSON (/riderequest/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:294:16)
    at GoogleAuth.getClient (/riderequest/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:476:52)
    at GrpcClient._getCredentials (/riderequest/functions/node_modules/google-gax/build/src/grpc.js:107:40)
    at GrpcClient.createStub (/riderequest/functions/node_modules/google-gax/build/src/grpc.js:223:34)
    at new FirestoreClient (/riderequest/functions/node_modules/@google-cloud/firestore/build/src/v1/firestore_client.js:128:39)
    at ClientPool.Firestore._clientPool.pool_1.ClientPool [as clientFactory] (/riderequest/functions/node_modules/@google-cloud/firestore/build/src/index.js:315:26)
    at ClientPool.acquire (/riderequest/functions/node_modules/@google-cloud/firestore/build/src/pool.js:61:35)
    at ClientPool.run (/riderequest/functions/node_modules/@google-cloud/firestore/build/src/pool.js:114:29)
    at Firestore.request (/riderequest/functions/node_modules/@google-cloud/firestore/build/src/index.js:957:33)
⚠  Your function was killed because it raised an unhandled error.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 24
  • Comments: 61 (21 by maintainers)

Most upvoted comments

Disclaimer: not sure how related my problem was to this one here, but at least I can drop my info here as it might help some of you out.

I had the same in a firebase function which tries to update some document in firestore database in batch. (Didn’t test without batch).

This is the callstack:

Unhandled error Error: The incoming JSON object does not contain a client_email field
>      at JWT.fromJSON (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\jwtclient.js:165:19)
>      at GoogleAuth.fromJSON (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\googleauth.js:294:16)
>      at GoogleAuth.getClient (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\googleauth.js:476:52)
>      at GrpcClient._getCredentials (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-gax\build\src\grpc.js:107:40)
>      at GrpcClient.createStub (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-gax\build\src\grpc.js:223:34)
>      at new FirestoreClient (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\v1\firestore_client.js:128:39)
>      at ClientPool.Firestore._clientPool.pool_1.ClientPool [as clientFactory] (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\index.js:315:26)
>      at ClientPool.acquire (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\pool.js:61:35)
>      at ClientPool.run (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\pool.js:114:29)
>      at Firestore.readStream (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\index.js:995:26)

RESPONSE RECEIVED FROM FUNCTION: 500, {
  "error": {
    "status": "INTERNAL",
    "message": "INTERNAL"
  }
}

I was running my function locally using the command line: firebase functions:shell

I was using this code:

// Reference report in Firestore
const db = admin.firestore();

admin.initializeApp();

export const performMyCallableFirebaseFunction = (db,, { from, to }) => {
    return db.collection("collectionName").where("prop", "==", from).limit(500).get().then(snapshot => {
        if (snapshot.empty) return new Promise(resolve => resolve(`No docs found with prop: ${from}`));

        const batch = db.batch();
        snapshot.forEach(doc => batch.update(doc.ref, { prop: to }));

        return batch.commit();
    });
};
exports.myCallableFirebaseFunction = functions.https.onCall(data => performMyCallableFirebaseFunction(db, data.from, data.to));

I changed the line admin.initializeApp(); to admin.initializeApp({ credential: admin.credential.applicationDefault() }); and now I was able to call my function locally using:

firebase functions:shell
firebase > myCallableFirebaseFunction({from: "foo", to: "bar"})

See docs for admin.credential.applicationDefault()

Firebase Console > Settings (Gear icon) > Users and permissions > Service accounts

Generate new key.

Add json to your project folder.

var admin = require("firebase-admin");

var serviceAccount = require("path/to/serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://lts-profile.firebaseio.com"
});

The Service account json file makes your firebase services and features available to your project. It should always be private. Include file in .gitignore

The full fix for this issue has been released in 7.2.0:

npm install -g firebase-tools@7.2.0

If you are still experiencing a similar bug on that version, please open a new issue.

A fix for this was merged into #1479 and will be included in the next release (so 7.2.0)

Same issue with 7.1

@ryanhornberger you could work around your issue by doing:

const firebaseInstance = admin.initializeApp()
const firestoreInstance = admin.firestore() // I changed this line

I have a fix for that coming in #1459

serviceAccountKey.json should be in /functions directory.

the firebase deploy --only functions will complain if it’s outside.

I changed the line admin.initializeApp(); to admin.initializeApp({ credential: admin.credential.applicationDefault() });

This worked for me. I’m running functions locally via: firebase serve --only functions

It’s not clear to me is this is safe for production. From the docs it sounds like it would give admin access to the code running in production but that’s true anyways.

Everyone on this thread. We discovered a solution. We downgraded firebase-tools from 7.0.2 to 7.0.1 and received an entirely different error (something about not being able to load default credentials).

So we continued by running:

gcloud auth application-default login

This fixed our issue

@wceolin it wasn’t supposed to work like that with bare initializeApp() in versions after 6.8.0. I also have that use case but we want a find a way to make that opt-in so that the default is to protect production.

But I am glad to know where this error comes from now!