我有一个用户集合,我在其中存储用户数据,例如姓名,电子邮件等,以及另一个用于阻止用户的集合。我想允许用户阅读自己的文档以及他/她没有阻止的用户文档。我已经实现了安全规则,但是用户不知何故甚至无法阅读自己的文档。有人可以帮忙吗?
用户集合
users { // name of collection
a1 { // this is firebase id serving as document name
name: "abc",
email: abc@gmail.com
}
a2 { // this is firebase id serving as document name
name: "efg",
email: efg@gmail.com
}
a3 { // this is firebase id serving as document name
name: "hij",
email: hij@gmail.com
}
a4 { // this is firebase id serving as document name
name: "klm",
email: klm@gmail.com
}
}
阻止的收藏集
blocked { // name of the collection
a1 { // name of the document
a2 : 1, // this means a1 has blocked a2
a4 : 1 // this means a1 has blocked a4
}
}
安全规则
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read: if request.auth.uid != null
&& get(/databases/$(database)/documents/blocked/$(request.auth.uid)).userId != 1;
}
match /blocked/{fid} { // blocked collection/fid == owner firebase id
allow read: if request.auth.uid == fid;
}
}
}
代码
DocumentReference docref = Firestore.instance.collection("users").document(user.uid);
return docref.get();
答案 0 :(得分:2)
在这种情况下,您需要对userId
变量进行不同的处理。编写方式的规则是,在用户阻止的文档的userId
对象中寻找Resource
属性,而不是userId
变量的值。您可能还想为get
调用提供一个合理的默认值。
同样,由于get()
调用返回一个Resource,因此您需要使用data
成员来获取属性Map。
您可能需要另外检查用户的被阻止文档是否确实存在,否则查询将失败。
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read: if request.auth.uid != null
&& (!exists(/databases/$(database)/documents/blocked/$(request.auth.uid)) ||
get(/databases/$(database)/documents/blocked/$(request.auth.uid)).data.get(userId,0) != 1);
}
match /blocked/{fid} { // blocked collection/fid == owner firebase id
allow read: if request.auth.uid == fid;
}
}
}
以上内容应允许(考虑到您在问题中定义的/blocked
):
a1
阅读/users/a1
a1
阅读/users/a3
a2
读取/users
中的任何文档以上内容应否认:
a1
阅读/users/a2
我只在模拟器中对以上内容进行了一些宽松的验证。我强烈建议您write extensive tests使用最终使用的任何规则。
最后,请记住security rules are not filters,所以它实际上取决于您的使用方式-可能会拒绝任何个可能匹配文档的查询将拒绝整个查询。您描述问题的方式(使用拒绝用户访问其阻止的其他用户的文档的规则)听起来就像您在尝试过滤而不是在保护数据。