TLDR:一个凭证有效,而另一个凭证无效吗?
我有2个针对Cloud Firestore的Google Cloud项目。一种用于生产,一种用于开发。
注意:我不使用Firebase,仅使用Firestore。
项目1(产品)::使用生产凭据,部署到GAE(Google App Engine)的代码可以很好地访问Firestore。 GAE和Firestore共享同一个项目。
项目2(dev):我的本地代码可以使用开发凭据(我已指定为开发沙箱的项目)访问Firestore
现在是问题所在:
错误:7 PERMISSION_DENIED:缺少权限或权限不足。
那是我运行以下代码时遇到的错误。
// script.js
//
// In my local environment (my laptop), I want to run a script that queries my
// "Production Firestore" and do some analysis.
const Firestore = require('@google-cloud/firestore');
const prodProjectKey = require('./keys/prod.json')
const db = new Firestore({
credentials: {
client_email: prodProjectKey.client_email,
private_key: prodProjectKey.private_key,
},
})
;(async () => {
const doc = await db.collection('users').doc('123').get()
})()
现在,对我来说并不奇怪,如果我更改凭据以使用开发凭据,一切正常。
// To be super clear, the following works
// (the only difference is using dev.json instead of prod.json)
const devProjectKey = require('./keys/dev.json')
const db = new Firestore({
credentials: {
client_email: devProjectKey.client_email,
private_key: devProjectKey.private_key,
},
})
;(async () => {
const doc = await db.collection('users').doc('123').get()
})()
据我所知,这些键之间的唯一区别是项目ID。我遵循相同的步骤来创建它们: Google Cloud Console->服务帐户->创建服务帐户->分配项目所有者角色->创建密钥->下载密钥
关于SO的其他问题,我也指向“数据库规则”,但是
答案 0 :(得分:1)
继续尝试,我终于找到了解决方法。
正确:
const db = new Firestore({
projectId: 'myproject',
keyFilename: '/absolute/path/to/prodProjectKey.json',
})
错误:
const db = new Firestore({
credentials: {
client_email: prodProjectKey.client_email,
private_key: prodProjectKey.private_key,
},
})
我应该注意,遇到任何相同问题的人都可以在Google Cloud上运行“错误”代码。只有在本地运行时,才会弹出PERMISSION_DENIED错误。
回想一下,当您查看prodProjectKey.json的内容时,我认为原因很明显:
{
"type": "service_account",
"project_id": "xxxx",
"private_key_id": "xxxx",
"private_key": "-----BEGIN PRIVATE KEY-----xxxxxx\n-----END PRIVATE KEY-----\n",
"client_email": "xxxx@xxx.iam.gserviceaccount.com",
"client_id": "xxxx",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "xxx"
}
当您在Google Cloud上运行时提供client_email和private_key时,Google Cloud可以从服务器环境中推断其他重要参数,例如project_id。当它在本地运行时,不能。
答案 1 :(得分:0)
您所描述的行为实际上是预期的和正确的。您无法使用其他项目中的密钥,因为该密钥是根据与之相关的每个服务帐户和projectId生成的,您可以查看此documentation上的示例以获取更多详细信息。
根据firebase规则,您无法在Cloud Console上对其进行编辑,但是您也可以使用Firebase CLI通过版本控制进行部署,在此documentation上有一个方法。
注意:作为Cloud Console用户,您可以访问Firebase Console而无需支付额外费用,因此,我不明白为什么要编辑规则对您的项目造成问题通过那里。另外,如果您选择使用Firebase CLI,如先前共享的文档所述:
使用Firebase CLI部署安全规则时,在项目目录中定义的规则将覆盖Firebase控制台中的所有现有规则。因此,如果您选择使用Firebase控制台定义或编辑安全规则,请确保还更新在项目目录中定义的规则。
希望这会有所帮助。