来自不同集合的条件的 Firestore 规则

Posted

技术标签:

【中文标题】来自不同集合的条件的 Firestore 规则【英文标题】:Firestore rule on condition from a different collection 【发布时间】:2018-05-31 16:47:23 【问题描述】:

我有一个包含两个集合的 Firestore 数据库:用户和锦标赛。用户具有“参与者”角色和“管理员”角色,并由用户文档中的“isParticipant”和“isAdmin”布尔值表示:

/users/userId:
  isParticipant: true
  isAdmin: true

我为这些集合设置了访问规则,如下所示:

service cloud.firestore 
  match /databases/database/documents 
     match /users/userId 
      allow create, read;
      allow update: if request.auth.uid == userId;
    
     match /tournaments/tournamentId 
      allow create, read, update: if request.auth.uid != null;
    
  

但是,我真正想做的是将锦标赛的创建限制为“管理员”角色的用户。我已经在代码中执行此操作,但希望增加 db 规则的安全性,以防止除管理员用户之外的任何人创建锦标赛。

有没有办法在规则语法中引用不同集合的数据元素?比如:

     match /tournaments/tournamentId 
      allow create: if resources.users.userId.isAdmin == true;
    

?

提前致谢。

【问题讨论】:

【参考方案1】:

您可以使用get 函数访问不同集合中的数据:

 // Allow the user to delete cities if their user document has the
 // 'admin' field set to 'true'
 allow delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true

有关这方面的更多信息,请参阅 Firebase 文档中的 access other documents,这是我从中获得上述示例的地方。

需要注意的一点是,这需要阅读额外的文档。如果您将用户是管理员的事实他们的个人资料中存储为自定义声明,则可以从request.auth 访问它,而无需额外阅读。例如

allow delete: if request.auth.token.admin == true

有关这方面的更多信息,请参阅文档中的 control access with custom claims 和 accessing the user token。

【讨论】:

谢谢。我不知道自定义声明功能。声明是否在 Firestore 控制台中的任何位置可见?即,我是否能够更改索赔的价值而无需以编程方式进行? 我认为这些声明不会出现在控制台中,但这会是一个很棒的feature request。现在,您必须通过 Admin SDK 或在客户端中获取它们。

以上是关于来自不同集合的条件的 Firestore 规则的主要内容,如果未能解决你的问题,请参考以下文章

使用 exists() 的 Cloud Firestore 规则是不是算作读取?

仅当 UID 与 Firebase Firestore 中的集合名称匹配时,如何读取集合?

使用规则禁用 Firebase Cloud Firestore 中的查询集合

Firestore 规则 - 动态路径

如何在 Flutter 中加入来自两个 Firestore 集合的数据?

基于角色的 Firestore 规则