无法理解Firebase数据库规则

时间:2016-06-11 16:02:37

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

这一定是容易做的事情,而且我做了一些愚蠢的事情,但是4个小时我无法理解我做错了什么。 我有像这样的数据库实体:

posts:
    -KK-3ajDuSUglnMMdXgy
       authorId: "DYI4TPbwQocFsVROStUqcGNFHhW2"
       authorName: "john"
       privacy: "PrivacyTypeWorld"
       text: "some post text"

帖子可以有3个级别的隐私:适用于所有(PrivacyTypeWorld),仅适用于作者(PrivacyTypePrivate),适用于朋友(friendId,friendId,...)。

我的安全规则如下所示:

{
  "rules": {
     "posts": {
        ".read": "auth != null && (data.child('privacy').val() === 'PrivacyTypeWorld')",
        ".write": "auth != null"
      }
   }
}

但是按照这个规则我什么也看不见。如果我设置".read": "auth != null" - 一切正常。 我做错了什么?

修改

要检索我使用的数据:

_refHandle = [[_ref child:@"posts"] observeEventType:FIRDataEventTypeChildAdded
                                      withBlock:^(FIRDataSnapshot *snapshot) {
                [_arrPosts addObject:snapshot];
                [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:_arrPosts.count-1 inSection:0]] withRowAnimation: UITableViewRowAnimationAutomatic];
          }];

2 个答案:

答案 0 :(得分:1)

你有两个错误:

  1. 您的规则定义了错误级别的访问权限(正如@adolfosrs所说)。通过意识到没有节点posts/privacy最容易理解,因此检查将始终返回false。相反,您应该在posts/$postid上授予访问权限,以便您检查posts/$postid/privacy

  2. 您正在尝试阅读posts。 Firebase查询始终会检查您读取/查询的级别的权限。由于您未授予posts的读取权限,因此查询将失败。

  3. 这最后一位通常称为"rules are not filters" or "rules cannot be used to filter data"。关于这个问题的最佳答案是Restricting child/field access with security rules

    您的案例中最简单的解决方案似乎是将世界上可读的帖子放在一个单独的顶级节点中,您可以在其中授予每个人读取权限:

    posts:
        -KK-3ajDuSUglnMMdXgy
           authorId: "DYIciaiew98acohzxvx09qw"
           authorName: "puf"
           text: "Only authenticated users can write this"
    publicPosts:
        -KK-3ajDuSUglnMMdXgy
           authorId: "DYI4TPbwQocFsVROStUqcGNFHhW2"
           authorName: "john"
           text: "Everyone can read this"
    

    这些规则:

    {
      "rules": {
         "posts": {
            ".read": "auth != null",
            ".write": "auth != null"
          }
         "publicPosts": {
            ".read": true,
            ".write": "auth != null"
          }
       }
    }
    

答案 1 :(得分:0)

你没有进入每个帖子。您正在寻找de posts内的隐私而不是posts / postId。

在以下规则中,$post指的是帖子ID。因此,如果您想使用任何其他验证,您还可以使用读取或写入中的$post来处理帖子ID。

{
  "rules": {
     "posts": {
        "$post": {
            ".read": "auth != null && (data.child('privacy').val() === 'PrivacyTypeWorld')",
            ".write": "auth != null"
        }
      }
   }
}