Firestore 安全规则 - 允许基于其父文档数据读取子集合

Posted

技术标签:

【中文标题】Firestore 安全规则 - 允许基于其父文档数据读取子集合【英文标题】:Firestore Security Rules - allow read subcollection based on its parent document data 【发布时间】:2021-01-23 01:01:37 【问题描述】:

我正在使用 Firestore 实现一个聊天应用程序,并且我在集合“chats/”中的每个聊天室都有一个文档,该集合有一个包含房间中所有消息的子集合“messages/”。

为了访问这个子集合,我需要检查用户是否被允许阅读它,检查他是否在父文档中的成员数组中。

/chats
    /chatId
        /messages (subcollection)
            /messageId
        - members array (field)

目前,我正在这样做:

function isSignedIn() 
   return request.auth.uid != null;


match /chats/chatId 
    function isUserInChatRoom() 
      let userId = request.auth.uid;
      // A user is in the chatroom if he is in its members list
      return userId in resource.data.members;
    
      
    // Only signed users which are in the chatroom can read its data
    allow read: if isSignedIn() && isUserInChatRoom(); 
       
    // The client side cannot modify the chats collection
    allow write, update, delete: if false;
      
    match /messages/document=** 
      // Only signed users which are in the chatroom can read its messages
      allow read: if isSignedIn() && isUserInChatRoom();
    

但是,似乎 isUserInChatRoom() 在消息子集合中不起作用。

我怎样才能做到这一点?

【问题讨论】:

使用 get() 访问父数据 你能举个例子吗 阅读文档firebase.google.com/docs/firestore/security/… 【参考方案1】:

我不太喜欢安全规则语法,但你可以试试这个(基于文档)

match /chats/chatId 
  function isUserInChatRoom() 
    let userId = request.auth.uid;
    // A user is in the chatroom if he is in its members list
    return userId in resource.data.members;
  

  function getChatRoomData() 
     return get(/databases/$(database)/documents/chats/$(chatId)).data;
  
      
  // Only signed users which are in the chatroom can read its data
  allow read: if isSignedIn() && isUserInChatRoom(); 
       
  // The client side cannot modify the chats collection
  allow write, update, delete: if false;
      
  match /messages/document=** 
    function canReadMessages() 
      let userId = request.auth.uid;
      // A user can read the chatroom messages if he is a member of the chatroom
      return userId in getChatRoomData().members;
    
        
    // Only signed users which are in the chatroom can read its messages
    allow read: if isSignedIn() && isUserInChatRoom();
  

【讨论】:

以上是关于Firestore 安全规则 - 允许基于其父文档数据读取子集合的主要内容,如果未能解决你的问题,请参考以下文章

基于引用数据类型的 Firebase Firestore 安全规则

即使firestore安全规则中的文档字段不可用,也如何允许访问?

Cloud Firestore 安全规则只允许从 Firebase 函数写入

Firebase Firestore - 基于“where”查询参数的安全规则

Firebase Firestore 安全规则 |如果字段值与 auth uid 相同,则允许读取

Cloud Firestore 安全规则 -(读取、写入)