Firebase 数据库 AuthVariableOverride 不工作

Firebase databaseAuthVariableOverride not working

我关注了这些 Firebase directions,在过去的几周里,我一直在使用 databaseAuthVariableOverride 让用户使用 Algolia 在我的应用程序中 运行 搜索结果并访问数据库.我今天早些时候更改了我的 Firebase 服务帐户 API 密钥,现在 databaseAuthVariableOverride 不再有效,我无法访问数据库。

在我更改 Api 密钥之前,当我将规则和 app.js 文件设置为 :

时一切正常

Firebase 规则:

{
  "rules": {
    ".read": "auth.uid === 'my-service-worker'", // matches the databaseAuthVariableOverride
    ".write": "auth.uid != null"
  }
}

和我的 App.js 文件到:

var admin = require("firebase-admin");
admin.initializeApp({
  credential: admin.credential.cert({
    projectId: .....,
    privateKey: "-----BEGIN PRIVATE KEY-----oldPrivateKey----END PRIVATE KEY-----\n",
    clientEmail: .....
  }),
  databaseURL: .....,
  databaseAuthVariableOverride: {
       uid: "my-service-worker" // matches the rules
    }
});

当我更改我的服务帐户时,我去了 ProjectOverview > ProjectSettings > ServiceAccounts > 生成新私钥。按 生成新私钥 后,一个新密钥已下载到我的 cpu。

我检查了 IAM 中的权限,服务帐户客户端电子邮件设置为 Editor

然后我将生成的看起来像 -----BEGIN PRIVATE KEY-----newPrivateKey----END PRIVATE KEY-----\n 的新私钥复制并粘贴到我的 app.js 文件中,我的旧私钥已设置在该文件中:

admin.initializeApp({
      credential: admin.credential.cert({
        // my new private key
        privateKey: "-----BEGIN PRIVATE KEY-----newPrivateKey----END PRIVATE KEY-----\n" 

现在唯一可行的方法是将我的 Firebase 规则设置为:

{
  "rules": {
    ".read": true,
    ".write": "auth.uid != null"
  }
}

API 键必须有效,否则我将无法阅读任何设置为 true

的规则

当我尝试按照原来的方式设置规则以匹配 my-service-worker 时,app.js 文件不再被授予对数据库的访问权限。

在评论中@Doug Stevenson 建议我更改新服务帐户附带的所有字段,但问题是我只使用了这 3 个旧服务帐户中的 3 个字段,唯一更改的是私钥。其他 2 个字段具有相同的值。 还有其他几个我从来没有开始使用过的:

这些是 app.js 文件中使用的值:

可能是什么问题?

更新 @Doug Stevenson 说每次生成一个新的服务帐户时,也应该生成一个新的客户电子邮件。我生成了 5 个服务帐户,前 4 个保留了相同的客户电子邮件。我不确定为什么会这样,但我去了 Google Cloud Console,生成了我自己的,删除了旧的,但没有任何效果。然后我回到带有蓝色按钮的 Firebase 控制台,按下它,然后我收到了一封新的客户电子邮件。我花了 5 次服务帐户下载才更改它???无论如何,我用新的客户端电子邮件更新了这些值,并且它是关联的私钥,但我的问题仍然存在。我也检查了权限,它设置为编辑器。

我已通过电子邮件向 Firebase 寻求帮助,正在等待回复。

如果要替换服务帐户,您需要更新所有证书字段值,而不仅仅是 privateKey 字段。

相反,理想情况下,您只是从项目中替换 require() 的整个 JSON 文件。这可能比在源文件中对所有内容进行硬编码要好得多,特别是如果您的项目是开源的并且您不想与世界共享您的凭据。或者甚至与您的同事一起使用不同的项目沙箱进行开发。

我对数据库进行了两次初始化,这就是 databaseAuthVariableOverride 无法正常工作的原因。

admin.initializeApp({
  credential: admin.credential.cert({
    projectId: process.env.FIREBASE_PROJECT_ID,
    privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\n/g, '\n'),
    clientEmail: process.env.FIREBASE_CLIENT_EMAIL
  }),
  databaseURL: process.env.FIREBASE_DATABASE_URL,
  databaseAuthVariableOverride: {
    uid: process.env.TOKEN
  }
});

// 1st initialization
const db = admin.database();
const firstRef = db.ref(process.env.INDEX_NAME); // I only needed to use this
firstRef.once("value", function(snapshot) {
  console.log(snapshot.val());
});

// ****2nd initialization****
const secondRef = firebase.database().ref(process.env.INDEX_NAME); // this second initialization was causing a problem with the first one

第二次初始化导致 databaseAuthVariableOverride 不起作用。一旦我将其注释掉,每次我将它从一个值更改为 null 并返回时,databaseAuthVariableOverride 就会开始工作。

我只需要使用firstRef作为基准参考,一切都很好。