【问题标题】:How to get a value without the unique user ID in a users node on Firebase Realtime DB?如何在 Firebase Realtime DB 上的用户节点中获取没有唯一用户 ID 的值?
【发布时间】:2020-12-21 14:07:53
【问题描述】:

我有一个这样的用户节点:

在这里,我需要访问appleId 字段,这是我的规则:

{
    "rules": {
      "users": {
        "$userId": {
          "single": {
            "public": {
              ".read": "true"
            }
          },
        }
      }
    }
}

因此,按照该规则,我应该读取存储在public 节点中的所有值。 这是我用 NodeJS 编写的代码

const data = firebase
  .database()
  .ref("users/XzIvC5GUKPesQybZWfrxsSSXpMt2")
  .child('single')
  .child('public')
  .child('appleId')
  .once("value");

data.then((ss) => {
  console.log(ss.val());
});

这很好用。但我需要搜索appleId,所以我尝试了这个:


const data = firebase
  .database()
  .ref("users")
  .child("single")
  .child("public")
  .child("appleId")
  .equalTo("000072.b185925fe1f1431dad013b66f9ceb8d1.1155")
  .once("value");

data.then((ss) => {
  console.log(ss.val());
});

firebase 给出了这个错误; (node:5131) UnhandledPromiseRejectionWarning: Error: permission_denied at /users/single/public/appleId: Client doesn't have permission to access the desired data.

我的意思是在没有用户 ID 的情况下搜索 appleId。我怎样才能做到这一点?我应该改变我的规则还是代码有问题?

【问题讨论】:

  • 您在问题中包含了 JSON 树的图片。请将其替换为实际的 JSON 作为文本,您可以通过单击 your Firebase Database console 的溢出菜单 (⠇) 中的 Export JSON 链接轻松获得。将 JSON 作为文本使其可搜索,允许您删除不想共享的值,并允许我们轻松使用它来测试您的实际数据并在我们的答案中使用它,一般来说这只是一件好事做。

标签: node.js firebase firebase-realtime-database firebase-security


【解决方案1】:

我认为您要做的是根据用户的single/public/appleId 属性的值来查找用户。如果是这样,查询将是:

firebase
  .database()
  .ref("users")
  .orderByChild("single/public/appleId")
  .equalTo("000072.b185925fe1f1431dad013b66f9ceb8d1.1155")

因此,子节点的排序/过滤路径被传递到 orderByChild,而不是作为一组 child() 调用。


但这仍然不适用于您的安全规则,因为您需要拥有/users 的读取权限才能执行此查询。

因此,您应该将具有单独访问要求的数据放入单独的顶级节点中。数据结构中的 public 是一个典型的标志,表明您希望将此数据拉入其自己的更高级别节点,您可以在其中授予每个人读取权限,因此:

"users": {
  "uid1": { ... }
},
"users_public": {
  "uid1": {
    "appleId": "000072.b185925fe1f1431dad013b66f9ceb8d1.1155"
  }
}

使用此结构,您可以使用以下方法查询数据:

firebase
  .database()
  .ref("users_public")
  .orderByChild("appleId")
  .equalTo("000072.b185925fe1f1431dad013b66f9ceb8d1.1155")

唯一的替代方法是,如果您要过滤的值存在于用户的身份验证令牌中(例如他们的 UID)。比如说,您将 Apple ID 作为 custom claim 添加到用户的身份验证令牌中,称为 appleId,然后您可以在现有结构中允许 securely querying the data,如下所示:

{
  "rules": {
    "users": {
      ".read": "query.orderByChild == 'single/public/appleId' &&
                query.equalTo == auth.token.appleId" 
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 2017-10-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    相关资源
    最近更新 更多