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

时间:2021-01-23 01:01:37

标签: firebase google-cloud-firestore firebase-security

我正在使用 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() 在消息子集合中不起作用。

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分: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();
  }
}