我在Firebase Firestore中有以下数据结构来表示客户端和用户之间的多对多关系:
Clients
clientId1 {
users (object): {
userId1: true
userId2: true
}
}
clientId2 {
users (object): {
userId1: true
}
}
我使用以下查询在Android上查询:
db.collection("clients").whereEqualTo("users."+uid, true);
对于userId2,查询应该只返回clientId1。
如果我将规则设置为(允许读取:如果为true;)当我执行上面的查询时,我会返回正确的客户端。
我还想设置一个数据库规则,以防止userId2看到clientId2。
我尝试过这条规则,但我没有收到任何结果:
match /clients/{clientId} {
//Allow read if the user exists in the user collection for this client
allow read: if users[request.auth.uid] == true;
}
我也尝试过:
match /clients/{clientId} {
//Allow read if the user exists in the user collection for this client
allow read: if resource.data.users[request.auth.uid] == true;
}
但上述规则均未返回任何客户。
如何编写规则?
答案 0 :(得分:0)
根据有关Firestore Security Rules的官方文档:
在编写查询以检索文档时,请记住安全规则不是过滤器 - 查询是全部或全部。为了节省您的时间和资源,Cloud Firestore会针对其潜在结果集评估查询,而不是针对所有文档的实际字段值。如果查询可能返回客户端无权读取的文档,则整个请求将失败。
因此,您无法使用安全规则过滤数据库中存在的文档。
答案 1 :(得分:0)
我将回答我自己的问题,因为我只是在做一些愚蠢的事情。
我的数据结构很好,我的规则的正确语法就是这个:
match /clients/{clientId} {
//Allow read if the user exists in the user collection for this client
allow read: if resource.data.users[request.auth.uid] == true;
}
鉴于此:
Cloud Firestore针对其潜在结果集评估查询 而不是所有文档的实际字段值。如果一个 查询可能会返回客户端没有的文档 阅读权限,整个请求失败。
此Android查询可以正确实现规则的正确过滤器:
db.collection("clients").whereEqualTo("users."+uid, true);
我还没有正确实现我的适配器。我想看看我是否能够首先获得正确的数据结构/规则/查询。我是从另一个侦听整个客户端集合的监听器调用它的(它没有通过规则),因此没有调用此查询。之前,当我将规则设置为(允许读取:如果为true;)时,初始侦听器正在执行我的查询并返回正确的结果。这让我相信我的规则是不正确的,当时它不是。