web-dev-qa-db-fra.com

L'objet JSON entrant ne contient pas de champ client_email

J'essaie de créer une fonction cloud Firebase. Je voudrais donc exécuter ma fonction cloud Firebase localement. Mais cela ne fonctionne pas comment configurer l'authentification.

J'ai installé des outils Firebase: https://firebase.google.com/docs/functions/local-emulator J'ai exécuté la commande firebase login, maintenant je suis connecté. Ensuite, j'ai créé ma clé json avec ce tutoriel: https://cloud.google.com/docs/authentication/getting-started Maintenant, si je tape echo $GOOGLE_APPLICATION_CREDENTIALS le résultat est /home/$USER/.google/****.json qui contiennent

"project_id","private_key_id","private_key","client_email", "client_id",  "auth_uri", "token_uri", "auth_provider_x509_cert_url", "client_x509_cert_url"

J'ai également essayé d'installer la version complète de Google Cloud SDK et j'ai exécuté: gcloud auth application-default login mais sans succès.

Versions du package Npm:

"firebase-functions":"3.0.2"
"firebase-admin": "8.2.0"

Je pense avoir fourni suffisamment d'informations mais n'hésitez pas à m'en demander plus si vous le souhaitez.

const functions = require("firebase-functions");
const admin = require("firebase-admin");
const express = require("express");
const app = express();
app.get("/", async (req, res) => {
admin.firestore().collection('something').get().then((collection) =>
    return res.send({"count": collection.docs.length, "status": 200});
});
exports.exports = functions.https.onRequest(app);

le code n'est pas important, la chose la plus importante est que même j'ai fait toutes ces étapes, quand j'émule ma base de feu localement avec firebase serve et je déclenche une fonction, j'ai cette erreur: Erreur: l'objet JSON entrant ne contient pas de champ client_email

Je peux vous assurer que le fichier json contient le champ client_email.

Pouvez-vous m'aider à m'authentifier avec google?

Merci de votre aide.

22
Shining

J'avais un problème similaire. C'est probablement un bogue dans la version 7.0.2 de firebase-tools. Je suis revenu à la version 7.0.0 et ça marche maintenant.

La solution temporaire est donc:

npm i [email protected] -g  
18
tomexx

En bref:

admin.initializeApp({ credential: admin.credential.applicationDefault() });

Voir les documents pour admin.credential.applicationDefault ()

Mise à jour: Notez que cela n'est recommandé que pour les tests/expérimentations:

Cette stratégie est utile lors des tests et des expérimentations, mais peut rendre difficile la détermination des informations d'identification utilisées par votre application. Nous vous recommandons de spécifier explicitement les informations d'identification que l'application doit utiliser, ... Source

Un peu plus d'informations

J'ai eu la même chose en essayant d'appeler une fonction Firebase localement qui essaie de mettre à jour certains documents dans la base de données Firestore en lot. (N'a pas testé sans lot).

Pour commencer à appeler des fonctions Firebase localement, j'utilise:

firebase function:Shell

Comme vous le savez probablement, cela répertorie les fonctions disponibles pour votre projet.

J'ai appelé ma fonction et j'ai reçu la pile d'appels d'erreur suivante:

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

J'exécutais ma fonction localement en utilisant la ligne de commande: firebase functions:Shell

J'utilisais ce 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));

J'ai changé de ligne

admin.initializeApp();

à

admin.initializeApp({ credential: admin.credential.applicationDefault() });

et maintenant j'ai pu appeler ma fonction localement en utilisant:

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

Voir les documents pour admin.credential.applicationDefault ()

11
ThdK

Vous devrez probablement configurer le SDK Admin Firebase pour utiliser l'émulateur Firebase. Vous pouvez le faire en passant une propriété credential lors de l'appel de la méthode admin.initializeApp():

const serviceAccount = require('../serviceAccount.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});

Vous pouvez télécharger le fichier JSON de votre compte de service dans la console Firebase:

  • Cliquez sur l'icône "paramètres";
  • Allez dans "Utilisateurs et autorisations";
  • Cliquez sur le lien où il est écrit "N comptes de service ont également accès à ce projet";
  • Cliquez sur le bouton "Générer une nouvelle clé privée".
4
Will

Voici comment j'ai résolu le problème après quelques heures de difficultés:

Réponse courte:

Créer une clé Firebase-adminsdk

Comment faire:

  • Aller à Google-cloud-platform > Service accountshttps://console.cloud.google.com/iam-admin/serviceaccounts/

  • Sélectionnez votre projet

  • Sélectionnez votre firebase-admin-sdk ressemble à firebase-adminsdk-u4k3i@example..
  • Activer le mode édition
  • Create key et sélectionnez JSON
  • Vous avez la possibilité de télécharger un .json. Qui a ProjectID, PrivateKey and ClientEmail dedans
  • utilisez les informations comme celle-ci pour initialiser votre application:
// Providing a service account object inline
admin.initializeApp({
    credential: admin.credential.cert({
        projectId: "<PROJECT_ID>",
        clientEmail: "foo@<PROJECT_ID>.iam.gserviceaccount.com",
        privateKey: "-----BEGIN PRIVATE KEY-----<KEY>-----END PRIVATE KEY-----\n"
    })
});
3
buryo

Une fois que vous avez créé un projet Firebase, vous pouvez initialiser le SDK avec une stratégie d'autorisation qui combine votre fichier de compte de service avec les informations d'identification par défaut de l'application Google.

Pour authentifier un compte de service et l'autoriser à accéder aux services Firebase, vous devez générer un fichier de clé privée au format JSON.

Pour générer un fichier de clé privée pour votre compte de service:

  1. Dans la console Firebase, ouvrez Paramètres> Comptes de service.

  2. Cliquez sur Générer une nouvelle clé privée, puis confirmez en cliquant sur Générer une clé.

  3. Stockez en toute sécurité le fichier JSON contenant la clé.

Définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS sur le chemin de fichier du fichier JSON qui contient votre clé de compte de service. Cette variable ne s'applique qu'à votre session Shell actuelle, donc si vous ouvrez une nouvelle session, définissez à nouveau la variable.

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

https://firebase.google.com/docs/admin/setup?authuser=

2
Gavialis

J'obtenais cette erreur lors de l'exécution de firebase emulators:start.

Selon l'enquête de ce bogue: https://github.com/firebase/firebase-tools/issues/1451 , il semble que ce soit un problème de référencement de l'application directement au lieu de via l'administrateur module.

c'est-à-dire que cela provoque l'erreur:

const app = admin.initializeApp();
const firestore = app.firestore();

mais cela ne signifie pas:

admin.initializeApp();
const firestore = admin.firestore();

Cependant, pour la question d'origine, vous utilisez admin.firestore () afin que ce ne soit pas le problème. Il semble que admin.initializeApp() ne soit jamais appelé. Peut-être que cela pourrait être la cause de votre problème?

0
Noel