web-dev-qa-db-ja.com

着信JSONオブジェクトにclient_emailフィールドが含まれていません

Firebaseクラウド関数を作成しようとしています。そこで、firebaseクラウド機能をローカルで実行します。ただし、認証の設定方法は機能しません。

Firebaseツールをインストールしました: https://firebase.google.com/docs/functions/local-emulator コマンドfirebase loginを実行したので、ログに記録されます。次に、このチュートリアルでjsonキーを作成しました。 https://cloud.google.com/docs/authentication/getting-startedecho $GOOGLE_APPLICATION_CREDENTIALSと入力すると、結果は/home/$USER/.google/****.json含む

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

また、完全なgoogle cloud sdkをインストールしようとしましたが、私はgcloud auth application-default loginを実行しましたが、成功しませんでした。

Npmパッケージバージョン:

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

私は十分な情報を提供したと思いますが、必要に応じて私にもっと遠慮なく尋ねてください。

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);

コードは重要ではありませんが、最も重要なことは、これらの手順をすべて実行しても、firebase serveを使用してローカルでFirebaseをエミュレートし、関数をトリガーすると、次のエラーが発生します:エラー:受信JSONオブジェクトclient_emailフィールドを含まない

Jsonファイルにclient_emailフィールドが含まれていることを確認できます。

グーグルで認証するのを手伝ってくれませんか?

ご協力いただきありがとうございます。

22
Shining

同様の問題がありました。 7.0.2のバージョンfirebase-toolsのバグの可能性があります。バージョン7.0.0にロールバックしましたが、現在は機能しています。

したがって、一時的な解決策は次のとおりです。

npm i [email protected] -g  
18
tomexx

要するに:

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

admin.credential.applicationDefault() のドキュメントを参照してください

更新:これはテスト/実験にのみ推奨されることに注意してください:

この戦略は、テストや実験を行うときに役立ちますが、アプリケーションが使用している認証情報を判別するのが難しくなる可能性があります。アプリケーションで使用する資格情報を明示的に指定することをお勧めします... Source

もう少し情報

Firebaseデータベースの一部のドキュメントをバッチで更新しようとするFirebase関数をローカルで呼び出そうとしたときも同じでした。 (バッチなしでテストしませんでした)。

ローカルでfirebase関数の呼び出しを開始するには、以下を使用します。

_firebase function:Shell
_

おそらくご存知のとおり、これはプロジェクトで使用可能な関数のリストです。

私は自分の関数を呼び出し、次のエラー呼び出しスタックを取得しました:

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

コマンドラインを使用してローカルで関数を実行していた:_firebase functions:Shell_

私はこのコードを使用していました:

_// 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));
_

行を変えた

admin.initializeApp();

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

そして今私は自分の関数をローカルで呼び出すことができました:

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

admin.credential.applicationDefault() のドキュメントを参照してください

11
ThdK

おそらく、Firebaseエミュレータを使用するには、Firebase Admin SDKを設定する必要があります。これを行うには、admin.initializeApp()メソッドを呼び出すときにcredentialプロパティを渡します。

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

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

FirebaseコンソールでサービスアカウントのJSONファイルをダウンロードできます。

  • 「設定」アイコンをクリックします。
  • 「ユーザーと権限」に移動します。
  • 「N個のサービスアカウントもこのプロジェクトにアクセスできます」というリンクをクリックします。
  • 「新しい秘密鍵の生成」ボタンをクリックします。
4
Will

ここに私が数時間苦労した後に問題を解決した方法があります:

簡潔な答え:

Firebase-adminsdkキーを作成する

どうやってするの:

  • Google-cloud-platform > Service accountsにアクセス https://console.cloud.google.com/iam-admin/serviceaccounts/

  • プロジェクトを選択してください

  • firebase-admin-sdkfirebase-adminsdk-u4k3i@example..のように見えるものを選択します
  • 編集モードを有効にする
  • Create keyを選択し、JSONを選択します
  • .jsonをダウンロードするオプションが表示されます。 ProjectID, PrivateKey and ClientEmailが含まれている
  • アプリを初期化するには、次のような情報を使用します。
// 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

Firebaseプロジェクトを作成したら、サービスアカウントファイルとGoogleアプリケーションのデフォルト認証情報を組み合わせた承認戦略でSDKを初期化できます。

サービスアカウントを認証してFirebaseサービスへのアクセスを承認するには、JSON形式で秘密鍵ファイルを生成する必要があります。

サービスアカウントの秘密鍵ファイルを生成するには:

  1. Firebaseコンソールで、[設定]> [サービスアカウント]を開きます。

  2. [新しい秘密キーの生成]をクリックし、[キーの生成]をクリックして確認します。

  3. キーを含むJSONファイルを安全に保存します。

環境変数GOOGLE_APPLICATION_CREDENTIALSを、サービスアカウントキーを含むJSONファイルのファイルパスに設定します。この変数は現在のシェルセッションにのみ適用されるため、新しいセッションを開く場合は、変数を再度設定します。

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

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

2
Gavialis

_firebase emulators:start_を実行すると、このエラーが発生しました。

このバグの調査によると: https://github.com/firebase/firebase-tools/issues/1451 、これは管理者経由ではなく直接アプリを参照することに関する問題のようですモジュール。

つまり、これによりエラーが発生します。

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

しかし、これはしません:

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

ただし、元の質問では、admin.firestore()を使用しているため、問題はありません。 admin.initializeApp()が呼び出されることはないようです。おそらくそれがあなたの問題の原因である可能性がありますか?

0
Noel