Json 使用Firebase规则后,仍可读取过去10分钟的消息

Json 使用Firebase规则后,仍可读取过去10分钟的消息,json,firebase,time,firebase-realtime-database,Json,Firebase,Time,Firebase Realtime Database,我的Firebase实时数据库中有以下规则: { "rules": { "messages":{ "$key":{ // only messages from the last 10 minutes can be read ".read": "data.child('time').val() > (now - 600000)", } }, ".read": "auth != null", ".wri

我的Firebase实时数据库中有以下规则:

{
  "rules": {
    "messages":{
      "$key":{
        // only messages from the last 10 minutes can be read
        ".read": "data.child('time').val() > (now - 600000)",
      }
    },
    ".read": "auth != null",
    ".write": "auth != null"
  }
}
以及以下数据结构:

不幸的是,存在时间超过10分钟的邮件仍然可以读取。我的代码怎么了

摘要:要读取密钥的子项,用户必须经过身份验证,“时间”必须小于10分钟(600000毫秒)


恐怕我没有时间完成我的工作了!我愿意将我的赏金奖励给任何解决我问题的人。

这与Firebase规则级联的方式有关,如前所述:

请注意,数据库中较浅的.read和.write规则会覆盖较深的规则

进一步强调关于规则级联的一节中的要点,注意:

Firebase规则以这样一种方式级联,即向父节点授予读或写权限总是向所有子节点授予读/写访问权限

因此,在本例中,您的规则在
auth!=null
位于数据库的根级别,因此为任何已登录(或匿名授权)用户提供读写访问权限,即使您的其他
。更深入的read
规则似乎禁止这样做。根级别的规则具有优先级,因此基于时间的其他规则并不重要

您需要做的是删除根级别的
.read
规则,这将使邮件的读取规则生效;然后,如果数据库中有单独的部分,则根据需要为它们提供自己的规则

因此,如果“消息”和“用户”有单独的部分,那么您的规则可能如下所示:

{
  "rules": {
    "messages":{
      "$key":{
        ".read": "data.child('time').val() > (now - 600000) && auth != null",
      }
    },
    "users":{
      ".read": "auth != null",
    },
  ".write": "auth != null",
  }
}

其中,“messages”
.read
规则要求用户获得授权,并且在指定的时间限制内。“用户”节点下数据的
.read
规则只需要授权用户,而“
.write
规则位于根级别,因此适用于任何授权用户可以写入的所有内容。

该规则不起作用的原因是,您在读取后使用了读取,因此它取代了上述读取

{
  "rules": {
    "messages":{
      "$key":{
        ".read": "auth != null && data.child('time').val() > (now - 600000)",
      }
    },
    ".write": "auth != null"
  }
}

这将很好

你如何设置时间条目?@Lewis我认为这不重要,因为无论我给“时间”赋值多少,都不会发生任何事情。谢谢你的回答。但是,你能告诉我如何放置
。.read:“data.child('time').val()>(现在为-600000)”
。.read:“auth!”null“
(后者适用于整个数据库)在同一时间正确地在我的情况下?用户根本无法读取。让我们调查一下。我的数据结构是否与您的代码匹配?修订的摘要:要读取密钥的子项,用户必须经过身份验证,“时间”必须小于10分钟(600000毫秒).hmm,我没有一个实际的项目来完全测试这种情况。这个规则应该适用于单个消息。这假设您知道消息的id并尝试读取它,而不是将侦听器附加到“消息”上“节点。相反,如果您想询问messages节点中所有符合条件的子节点,也许您应该使用Query进行调查。@Programmer:Lewis的规则对于读取单个消息是正确的。侦听器必须设置在特定的消息位置,例如
mDatabase.getReference(“messages”).child(“msg1”)
。请注意,他的回答没有为
消息
节点指定任何规则。因此,尝试使用类似于
mDatabase.getReference(“messages”).orderByChild(“time”)
的方法来查询
消息
,将失败,因为未授予对位置
消息
的访问权限。无法为单个邮件指定所需的期限条件并将其应用于所有邮件的查询中。