Firebase Firestore 安全规则 - 根据资源读取所有嵌套文档(但为空)



我想我做错了什么,但我不知道是哪一部分。。。谢谢你给我的澄清。

所以我有一个名为Bases的集合,看起来像这样:

{
"id1": {
"name": "My base 1",
"roles": {
"idUser_123": {
"name": "John"
}
}
},
"id2": {
"name": "My base 2",
"roles": {
"idUser_456": {
"name": "Jane"
}
}
}
}

idUser_123登录并希望访问他的收藏。所以我会:db.collection('bases').get()

我用匹配规则来确保约翰没有读到简的底数。这就是我认为我错的地方,因为我使用规则是为了过滤。

match /bases/{document=**}{
allow read: if request.auth.uid in resource.data.roles;
}

失败,因为资源为null。。。我试着这样做:

match /bases/{baseId}{
allow read: if request.auth.uid in resource.data.roles;
}

当请求特定文档时,这在模拟器中起作用,但当我从客户端获得没有baseId的get((时失败,因为我想要它们。

那么,我应该如何处理这个非常基本的用例(IMO(呢?

我不能把所有用户的baseId都放在user.token中,因为它会很快超过1000字节。

我可以创建另一个集合Roles来创建baseId和我的用户之间的关系,但对于一个简单的用例来说,这似乎过于复杂了。

或者我可以在服务器上提出请求并过滤where("roles", "has", user.uid)?在我看来,很快就无法实现在客户端获取数据的目的。。。

任何关于如何解决这一问题的建议都将不胜感激!非常感谢:(

这里有两个问题。

首先,您的查询要求接收基地中的所有文档,但您的规则不允许任何人简单地接收所有文档。重要的是要认识到Firestore安全规则不是过滤器。他们不会从查询中剥离文档——这实际上是不可伸缩的。如果规则要求谁可以根据某些文档的内容查询这些文档,则查询必须使用符合规则要求的筛选器。

其次,您的数据的结构化方式不能使客户端根据用户的UID仅对某些文档执行筛选。Firestore没有可以检查映射字段是否存在的查询。它只能检查贴图值。您可能需要重新构造文档数据,以便客户端可以使用筛选器执行查询,从而仅获取当前用户的文档。

如果角色是一组UID:

"id1": {
"name": "My base 1",
"roles": [ "idUser_123" ]
},

然后客户端可以在该字段上进行过滤:

firebase.firestore()
.collection("bases")
.where("roles", "array-contains", uid)

你可以在规则中强制使用这个过滤器:

match /bases/{document=**} {
allow read: if request.auth.uid in resource.data.roles;
}

但你可能想做一些不同的事情。

最新更新