传入的 JSON 对象不包含 client_email 字段
Posted
技术标签:
【中文标题】传入的 JSON 对象不包含 client_email 字段【英文标题】:The incoming JSON object does not contain a client_email field 【发布时间】:2019-11-09 09:07:50 【问题描述】:我正在尝试创建一个 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);
代码并不重要,最重要的是即使我已经完成了所有这些步骤,当我使用firebase serve
在本地模拟我的firebase 并触发一个函数时,我有这个错误:
错误:
我可以确保 json 文件包含 client_email 字段。
您能帮我通过 google 进行身份验证吗?
感谢您的帮助。
【问题讨论】:
伙计,我已经在本地计算机上工作了 1 年,没有任何问题,现在我在过去 24 小时内收到此错误。所以,这应该是一个时间问题。 我也有同样的问题 【参考方案1】:这是我在挣扎了几个小时后解决问题的方法:
简答:
创建 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"
)
);
【讨论】:
【参考方案2】:简而言之:
admin.initializeApp( credential: admin.credential.applicationDefault() );
请参阅admin.credential.applicationDefault() 的文档
更新:请注意,这只建议用于测试/实验:
此策略在测试和试验时很有用,但可以使 很难判断您的应用程序正在使用哪些凭据。我们 建议明确指定应用程序的凭据 应该使用,...Source
更多信息
我在尝试在本地调用 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() 的文档
【讨论】:
【参考方案3】:我在运行 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()
。也许这可能是您的问题的原因?
【讨论】:
【参考方案4】:创建 Firebase 项目后,您可以使用将您的服务帐户文件与 Google 应用程序默认凭据相结合的授权策略来初始化 SDK。
要对服务帐号进行身份验证并授权其访问 Firebase 服务,您必须生成 JSON 格式的私钥文件。
为您的服务帐户生成私钥文件:
在 Firebase 控制台中,打开设置 > 服务帐户。
点击 Generate New Private Key,然后点击 Generate Key 确认。
安全存储包含密钥的 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
【讨论】:
【参考方案5】:我遇到了类似的问题。这可能是firebase-tools
的版本7.0.2
中的错误。我回滚到版本7.0.0
,现在可以使用了。
所以临时解决办法是:
npm i firebase-tools@7.0.0 -g
【讨论】:
7.0.1 也可以正常工作。每次使用functions:shell
时,7.0.2 都会为我抛出此错误
降级到 firebase-tools@7.0.0 对我有用。我想这个错误是在最新版本的 firebase-tools 中。
希望下一个信息对某人有用。降级到 7.0.0 后,我收到了错误 Getting metadata from plugin failed with error: invalid_grant
,我修复了删除文件 ~/.config/gcloud/application_default_credentials.json
(macOS) 并通过运行`gcloud auth application-default login` 重新创建它。【参考方案6】:
您可能需要设置 Firebase Admin SDK 才能使用 Firebase 模拟器。您可以通过在调用admin.initializeApp()
方法时传递credential
属性来实现:
const serviceAccount = require('../serviceAccount.json');
admin.initializeApp(
credential: admin.credential.cert(serviceAccount),
);
您可以在 Firebase 控制台中下载您的服务帐号 JSON 文件:
点击“设置”图标; 转到“用户和权限”; 点击显示“N 个服务帐户也可以访问此项目”的链接; 点击“生成新私钥”按钮。【讨论】:
我在 Firebase Admin SDK 页面上关注了这一点,并且成功了。谢谢。以上是关于传入的 JSON 对象不包含 client_email 字段的主要内容,如果未能解决你的问题,请参考以下文章
如何检查传入的 JSON 提要是不是包含单条记录或多条记录?
rxjs里的Observable对象subscribe方法的执行原理