允许用户只访问他们自己在 Firebase 数据库中的数据?

Allow users access only to their own data in Firebase database?

我正在尝试拥有这样的数据结构,并确保用户只能提取他们自己的数据,因为所有处理都是在客户端完成的。

我必须使用什么数据库安全规则才能让 User1 可以访问他们自己的帖子,但不能访问 User2 的帖子?

(我正在使用 Firebase 网络)

示例数据库结构:

{
  "posts" : {
    "001" : {
      "text" : "note 1",
      "userID" : "User1"
    },
    "002" : {
      "text" : "note 2",
      "userID" : "User1"
    },
    "003" : {
      "text" : "note 3",
      "userID" : "User2"
    }
  }
}

示例数据库查询:

firebase.database().ref('/posts/').once('value').then(function(snapshot) {
  console.log(snapshot.val()); // Returns all 3 posts
});

在您当前的结构中,很容易保护每个 post 的创建者的数据访问:

{
  "rules": {
    "posts": {
      "$postid": {
        ".read": "data.child('userID').val() === auth.uid"
      }
    }
  }
}

这就是所需要的:现在每个用户只能阅读他们自己的 posts。

但是这种方法有一个大问题:现在没有人可以从 /posts 读取,所以没有人可以得到所有 post 的列表。

要授予某人列出 post 的能力,您必须授予他们对 /posts 的读取权限。由于您无法撤销较低级别的权限,这意味着您此时他们可以阅读 所有 posts,而不仅仅是他们创建的那些。

这在 Firebase 中称为 rules are not filters: you cannot use rules to filter data. We've covered it quite a bit here on Stack Overflow, so I recommend you also check out some other questions on the topic

这个问题有很多解决办法。

二级索引

一个常见的解决方案是创建每个用户都可以访问的 post ID 的列表。这通常称为(二级)索引并将此附加数据添加到您的模型中:

{
  "userPosts" : {
    "User1": {
      "001" : true,
      "002" : true
    },
    "User2": {
      "003" : true
    }
  }
}

现在您可以像以前一样保护对原始 post 的访问,但随后可以使用以下方法保护对二级索引的访问:

{
  "rules": {
    "userPosts": {
      "$userid": {
        ".read": "$userid === auth.uid"
      }
    }
  }
}

因此每个用户都可以读取他们有权访问的 postID 列表,然后可以读取 /posts/postID 下的每个 post。

将每个用户的 post 存储在单独的节点下

对于您的情况,有一个更简单的解决方案。我会将该数据建模得稍微分层一些,每个用户的 posts 在他们自己的 UID 下:

{
  "posts" : {
    "User1": {
      "001" : {
        "text" : "note 1",
        "userID" : "User1"
      },
      "002" : {
        "text" : "note 2",
        "userID" : "User1"
      },
    },
    "User2": {
      "003" : {
        "text" : "note 3",
        "userID" : "User2"
      }
    }
  }
}

现在您可以通过以下方式安全访问:

{
  "rules": {
    "posts": {
      "$userid": {
        ".read": "$userid === auth.uid"
      }
    }
  }
}

每个用户都可以阅读和列出他们自己的 post。但是请牢记二级索引,因为您迟早可能需要它。