【问题标题】:Firebase Rules: Read restriction for dynamic child nodesFirebase 规则:动态子节点的读取限制
【发布时间】:2018-08-26 22:07:07
【问题描述】:

我正在尝试在具有一些嵌套动态子节点的数据模型中实施 Firebase 规则读取限制。

我有以下数据模型:

/groupMessages/<groupId>/<messageId>/

{
    "senderId": "<senderId>",
    "recipientId": "<recipientId>",
    "body": "..."
}

groupId、messageId、senderId 和 recipientId 是动态 id。我想在 /groudId 节点上附加一个监听器来监听新消息。同时我只希望用户阅读senderId或receiverId与相应的auth.token值匹配的消息。

由于 Firebase 级联规则,如果我允许在 groupId 级别不受限制地读取,我不能在消息级别拒绝它们。

{
    "rules": {
        "groupMessages"
           "$groupId": {
            ".read": "auth != null"
           }
        }   
    }
}

我还没有找到一种方法来限制 groupId 级别的读取规则以检查消息的发件人/收件人 ID。

非常感谢任何建议。

【问题讨论】:

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


    【解决方案1】:

    如您所见,安全规则不能用于过滤数据。但它们可用于限制可以对数据执行的查询。

    例如,您可以查询当前用户为发件人的所有邮件:

    var query = ref.child("groupMessages").child(groupId).orderByChild("senderId").equalTo(uid);
    

    并且您可以保护对群组消息的访问,只允许以下查询:

    {
      "rules": {
        "groupMessages": {
          "$groupId": {
            ".read": "auth.uid != null &&
                query.orderByChild == 'senderId' &&
                query.equalTo == auth.uid"
          }
        }
      }
    }
    

    查询和规则现在完全匹配,因此安全规则将允许查询,而它们会拒绝更广泛的读取操作。有关这方面的更多信息,请参阅 Firebase 文档中的 query based rules

    您会注意到这仅适用于单个字段。 Firebase 数据库查询只能过滤单个字段。虽然有 workarounds by combining multiple values into a single property,但我认为这些不适用于您的场景,因为它们仅适用于您似乎需要 OR 的 AND 查询。

    您似乎还想查询 /groupMessages 而不是特定组的消息。这也是不可能的:Firebase 数据库对属性进行排序/过滤,该属性位于运行查询的节点的每个子节点下的固定路径中。正如您似乎正在尝试的那样,您无法跨两个动态级别进行查询。有关更多信息,请参阅:Firebase Query Double NestedFirebase query if child of child contains a value

    您的问题的常见解决方案是为每个用户创建一个 ID 列表,其中仅包含他们有权访问的所有消息(和/或组)的 ID。

    userGroups: {
      uid1: {
        groupId1: true,
        groupId2: true
      },
      uid2: {
        groupId2: true,
        groupId3: true
      }
    }
    

    使用这个额外的数据结构(您可以更轻松地保护它),每个用户都可以简单地读取他们有权访问的组,然后您的代码会读取/查询每个组中的消息。如有必要,您也可以为消息本身添加类似的结构。

    最后:这种类型的递归加载并不像许多开发人员最初认为的那样低效,因为Firebase pipelines the requests over an existing connection

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-15
      • 1970-01-01
      • 1970-01-01
      • 2017-03-11
      • 2017-04-27
      • 1970-01-01
      • 2017-08-03
      • 2018-06-22
      相关资源
      最近更新 更多