我想我做错了什么,但我不知道是哪一部分......感谢我能得到的所有澄清。
所以我有一个名为 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;
}
由于资源为空而失败......我试图这样做:
match /bases/{baseId}{
allow read: if request.auth.uid in resource.data.roles;
}
这在请求特定文档时在模拟器中工作,但当我 get() 没有来自客户端的 baseId 时失败 - 因为我想要它们。
那么我应该如何处理这个非常基本的用例 (IMO)?
我不能把所有用户的 baseId 放在 user.token 中,因为它会很快超过 1000 个字节。
我可以创建一个其他集合角色来创建 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;
}
但你可能想做一些不同的事情。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句