22

我正在尝试创建一个 Firebase 云功能。所以我想在本地运行我的 firebase 云功能。但是如何设置身份验证不起作用。

我已经安装了 firebase 工具:https ://firebase.google.com/docs/functions/local-emulator 我已经运行了命令firebase login,所以现在我已经登录了。然后我用本教程创建了我的 json 密钥:https ://cloud.google.com/docs/authentication/getting-started 现在如果我输入echo $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);

代码并不重要,最重要的是即使我已经完成了所有这些步骤,当我在本地模拟我的firebasefirebase serve并触发一个函数时,我有这个错误:错误:传入的JSON对象不包含client_email场地

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

你能帮我通过谷歌进行身份验证吗?

谢谢你的帮助。

4

6 回答 6

18

我有一个类似的问题。这可能7.0.2firebase-tools. 我回滚到版本7.0.0,它现在可以工作了。

所以临时解决办法是:

npm i firebase-tools@7.0.0 -g  
于 2019-06-28T11:44:54.730 回答
12

简而言之:

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

请参阅admin.credential.applicationDefault()的文档

更新:请注意,这只建议用于测试/实验:

此策略在测试和试验时很有用,但会使您很难判断您的应用程序正在使用哪些凭据。我们建议明确指定应用程序应使用哪些凭据,...来源

更多信息

尝试在本地调用 firebase 函数时,我也遇到了同样的情况,该函数尝试批量更新 firestore 数据库中的一些文档。(没有批次没有测试)。

要开始在本地调用 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()的文档

于 2019-07-04T08:43:22.987 回答
4

您可能需要设置 Firebase Admin SDK 才能使用 Firebase 模拟器。您可以通过credential在调用admin.initializeApp()方法时传递一个属性来做到这一点:

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

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

您可以在 Firebase 控制台中下载您的服务帐号 JSON 文件:

  • 点击“设置”图标;
  • 转到“用户和权限”;
  • 单击显示“N个服务帐户也可以访问此项目”的链接;
  • 单击“生成新私钥”按钮。
于 2019-06-27T20:25:26.677 回答
3

这是我在挣扎了几个小时后解决问题的方法:

简短的回答:

创建 Firebase-adminsdk 密钥

怎么做:

  • 转到Google-cloud-platform > Service accounts https://console.cloud.google.com/iam-admin/serviceaccounts/

  • 选择您的项目

  • 选择你的firebase-admin-sdk样子firebase-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"
    })
});
于 2019-07-16T20:38:42.533 回答
2

创建 Firebase 项目后,您可以使用将服务帐户文件与 Google 应用程序默认凭据组合在一起的授权策略来初始化 SDK。

要对服务帐号进行身份验证并授权其访问 Firebase 服务,您必须生成 JSON 格式的私钥文件。

要为您的服务帐户生成私钥文件:

  1. 在 Firebase 控制台中,打开设置 > 服务帐户。

  2. 单击 Generate New Private Key,然后单击 Generate Key 进行确认。

  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

于 2019-06-28T11:49:36.397 回答
0

运行时出现此错误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()从未调用过。也许这可能是您的问题的原因?

于 2019-07-02T15:46:55.137 回答