如何在节点下存储公共/私有数据,并仍然查询整个节点

时间:2017-09-16 20:00:13

标签: firebase firebase-realtime-database firebase-security

我想将数据存储在$user下,其中一些数据是公众可读的,而某些数据只能由用户读取。安全规则看起来像这样:

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

但是,自security rules are not filters起,如果我$user试图在users/$user读取,那么读取会失败,对吗?有没有办法实现这一点,或者在尝试获取实际用户的所有users/$user/public信息时,我是否总是需要在users/$user/private$user执行阅读?

请注意,我希望避免重复数据,以减少重复数据与源节点保持同步的需要,以及在删除源节点时减少数据库清理。我的模式是唯一的密钥是唯一的重复数据,它始终指向源节点作为查询的位置。

1 个答案:

答案 0 :(得分:1)

如果您一次只阅读一个用户的信息,您提出的结构将正常工作 - 您只需在阅读公共信息时添加/public,或直接阅读$uid节点当作为用户访问并想要同时阅读公共和私人时。

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

users
  - public
    - $uid
  - private
    - $uid

一旦你达到这一点,是的,你将不得不做两次读取来访问这两个信息。记住一些事情:

  1. 私人信息只能由根据您的规则创作的用户读取,因此您可以在用户登录后立即在此单个节点上设置监听器,然后您将始终拥有该监听器。
  2. Firebase通过持续的实时连接进行连接,这意味着进行多次读取可能不像您想象的那么昂贵。
  3. 关于重复数据需要考虑的另一件事是,Cloud Functions for Firebase可以通过处理同步更新而无需在客户端中对其进行编码来使非规范化变得非常轻松。