javascript - 傳入的JSON對像不包含client_email字段




firebase google-cloud-functions (4)

我正在嘗試創建一個firebase雲功能。 所以我想在本地運行我的firebase雲功能。 但它不能如何設置身份驗證。

我安裝了firebase工具: https://firebase.google.com/docs/functions/local-emulator ://firebase.google.com/docs/functions/local-emulator我已經運行了命令 firebase login ,所以現在我已經登錄了。 然後我通過本教程創建了我的json密鑰: https://cloud.google.com/docs/authentication/getting-started/home/$USER/.google/****.json 現在,如果我輸入 echo $GOOGLE_APPLICATION_CREDENTIALS ,結果為 /home/$USER/.google/****.json 包含的 /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"

此外,我已經嘗試安裝完整的谷歌云sdk和我運行: gcloud auth application-default login 但沒有成功。

Npm包版本:

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

我想我已經提供了enought信息,但如果你願意,可以隨意問我。

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服務器本地模擬我的firebase並觸發一個函數時,我有這樣的錯誤:錯誤:傳入的JSON對像不包含client_email字段

我可以確保您的json文件包含client_email字段。

你能幫我用谷歌認證嗎?

謝謝你的幫助。


創建Firebase項目後,您可以使用將服務帳戶文件與Google Application Default Credentials結合使用的授權策略初始化SDK。

要對服務帳戶進行身份驗證並授權其訪問Firebase服務,您必須生成JSON格式的私鑰文件。

要為您的服務帳戶生成私鑰文件:

  1. 在Firebase控制台中,打開“設置”>“服務帳戶”。

  2. 單擊“生成新私鑰”,然後單擊“生成密鑰”進行確認。

  3. 安全地存儲包含密鑰的JSON文件。

將環境變量GOOGLE_APPLICATION_CREDENTIALS設置為包含服務帳戶密鑰的JSON文件的文件路徑。 此變量僅適用於當前的shell會話,因此如果打開新會話,​​請再次設置該變量。

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

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


您可能需要設置Firebase Admin SDK才能使用Firebase模擬器。 您可以通過在調用 admin.initializeApp() 方法時傳遞 credential 屬性來執行此 admin.initializeApp()

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

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

您可以在Firebase控制台中下載服務帳戶JSON文件:

  • 點擊“設置”圖標;
  • 轉到“用戶和權限”;
  • 點擊“N個服務帳戶也可以訪問此項目”的鏈接;
  • 單擊“生成新私鑰”按鈕。

運行 firebase emulators:start 時出現此錯誤 firebase emulators:start

根據此錯誤的調查: github.com/firebase/firebase-tools/issues/1451github.com/firebase/firebase-tools/issues/1451 ,這似乎是直接引用應用程序而不是通過管理模塊的問題。

即這會導致錯誤:

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

但這不是:

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

但是對於原始問題,您使用的是admin.firestore(),這樣就不會出現問題了。 似乎永遠不會調用 admin.initializeApp() 。 也許這可能是你問題的原因?


簡而言之:

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

請參閱 admin.credential.applicationDefault() 文檔

多一點信息

當我嘗試在本地調用firebase函數時嘗試更新firestore數據庫中的某些文件時,我也有同樣的想法。 (沒有批次沒有測試)。

要在本地開始調用firebase函數,我使用:

firebase function:shell

您可能知道,這列出了項目的可用功能。

我調用了我的函數並得到以下錯誤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"
  }
}

我使用命令行在本地運行我的函數: 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() 文檔





google-auth-library