Firebase规则:动态子节点的读取限制

时间:2018-08-26 13:28:39

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

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

我有以下数据模型:

/groupMessages/<groupId>/<messageId>/

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

groupId,messageId,senderID和收件人ID是动态ID。我想将侦听器附加到/ groudId节点以侦听新消息。同时,我只希望用户阅读senderId或receiveId与匹配的auth.token值匹配的消息。

由于Firebase的级联规则,如果我允许在groupId级别进行读取而没有任何限制,则不能在消息级别拒绝它们。

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

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

任何建议都值得赞赏。

1 个答案:

答案 0 :(得分:0)

您已经发现,安全规则不能用于过滤数据。但是它们可以用来限制可以对数据执行哪些查询。

例如,您可以使用以下方法查询当前用户是发件人的所有邮件:

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,但我认为这些不适用于您的情况,因为它们仅适用于AND查询,而您似乎希望使用OR。

您似乎还想查询/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开始,这种递归加载的效率并没有许多开发人员最初认为的那样低。