如何编写Firebase Firestore的读取规则多对多关系

时间:2018-05-07 01:55:47

标签: java android firebase google-cloud-firestore firebase-security-rules

我在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;

}

但上述规则均未返回任何客户。

如何编写规则?

2 个答案:

答案 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;)时,初始侦听器正在执行我的查询并返回正确的结果。这让我相信我的规则是不正确的,当时它不是。