如何在一个节点下存储public/private条数据,仍然查询整个节点

How to store public/private data under a node, and still query the entire node

我想将数据存储在 $user 下,其中某些数据可由 public 读取,而某些数据仅可由用户读取。安全规则看起来像这样:

{
  "rules": {      
    "users": {
      "$uid": {
        "public":{
          ".read": "auth != null",
        },
        "private": {
          ".read": "$uid === auth.uid"
        }
      }
    }
  }
}

但是,由于 security rules are not filters,如果我是 $user 试图读取 users/$user,读取会失败,对吗?有没有办法做到这一点,或者在尝试为实际用户获取所有 $user 信息时,我是否总是需要在 users/$user/publicusers/$user/private 处执行读取?

请注意,我想避免重复数据,以减少将重复数据与源节点保持最新的需要,以及在删除源节点时减少数据库清理。我的模式是唯一键是唯一的重复数据,它始终指向源节点作为查询的来源。

如果您一次只读取一个用户的信息,您建议的结构将工作正常——您可以在读取 public 信息时简单地总是添加 /public,或者读取 $uid 以用户身份访问并希望同时读取 public 和 private.

节点时直接

但是,如果您打算进行任何类型的查询,则此数据结构将无法正常工作,因为在不读取私有数据的情况下读取 public 数据时将无法进行查询。相反,您需要将 publicprivate 提升到 $uid 水平以上:

users
  - public
    - $uid
  - private
    - $uid

一旦你到达这一点,是的,你将必须进行两次读取才能访问这两种信息。不过请记住一些事情:

  1. 私人信息只能由根据您的规则创作它的用户读取,因此您可以轻松地在用户登录后立即在此单个节点上设置一个侦听器,然后您将始终拥有它。
  2. Firebase 通过持续的实时连接进行连接,这意味着进行多次读取并不像您想象的那么昂贵。

关于重复数据需要考虑的另一件事是,Cloud Functions for Firebase 可以通过处理更新时同步来使非规范化变得非常轻松,而无需在客户端对其进行编码。