首页  >  问答  >  正文

Firestore 规则拒绝对具有嵌套集合的聊天应用程序的每个请求。我究竟做错了什么?

我目前正在构建一个聊天应用,但遇到了 Firebase 规则的问题。我想限制用户看到他们不参与的对话。但是,当我尝试实施这些规则时,即使检查对话是否存在,访问似乎也会被拒绝。如何正确配置 Firebase 规则,以允许用户仅查看他们所属的对话,而不是数据库中的所有对话?

这是规则集,我试图仅为对话实现。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    
    // Allow users to read and write their own participant documents
    match /conversation/{conversationId}/participants/{userId} {
      allow read, write: if request.auth.uid == userId;
    }

    // Allow users to read and write messages in a conversation they are a participant of
    match /conversation/{conversationId}/messages/{messageId} {
      allow read, write: if exists(/databases/$(database)/documents/conversation/$(conversationId)/participants/$(request.auth.uid));
    }

    // Allow users to read and write their own conversation documents
    match /conversation/{conversationId} {
      allow read, write: if exists(/databases/$(database)/documents/conversation/$(conversationId)/participants/$(request.auth.uid));
    }
  }
}

访问已经在“最顶层”被拒绝,这就是这部分:

// Allow users to read and write their own conversation documents
    match /conversation/{conversationId} {
      allow read, write: if exists(/databases/$(database)/documents/conversation/$(conversationId)/participants/$(request.auth.uid));
    }

我认为,这与这些嵌套对话的工作方式有关,但我不知道我必须改变什么。我尝试在 google firebase 文档中阅读有关此内容的内容,但找不到任何与此相关的内容。 如果您有任何想法,如何解决此问题,请告诉我。谢谢!

我已经尝试让它与多个“规则集”一起使用。它总是在exists()函数处失败。

我也尝试过这个,但似乎也不起作用:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    function isUserInParticipants(conversationId) {
      return get(/databases/$(database)/documents/conversations/$(conversationId)/participants/$(request.auth.uid)).data != null;
    }

    match /conversations/{conversationId} {
      allow read, write: if request.auth != null && isUserInParticipants(conversationId);

      match /messages/{messageId} {
        allow read, write: if request.auth != null && isUserInParticipants(conversationId);
      }
    }
  }
}

这是我在 Vue.js 中使用的查询:

init() {
      const storeAuth = useStoreAuth();
      conversationCollectionRef = collection(db, 'conversation')
      conversationCollectionQuery = query(conversationCollectionRef) 
      this.getConversations()
    },
    async getConversations() {
      this.coversationsLoaded = false
      getConversationSnapshot = onSnapshot(conversationCollectionQuery, (snapshot) => {
        console.log('getConversations')
        console.log(snapshot)
        this.conversations = []
        snapshot.forEach((doc) => {
          this.getMessagesOfConversation(doc.id)
          const conversation = {
            id: doc.id,
            ...doc.data(),
          }
          this.conversations.push(conversation)
        })
      })
      this.coversationsLoaded = true
    },

P粉627136450P粉627136450407 天前502

全部回复(1)我来回复

  • P粉459578805

    P粉4595788052023-09-09 14:03:04

    您尚未共享正在运行的触发此故障的查询,但请务必记住Firestore 规则不是过滤器

    如果您的查询是这样的:

    firestore.collection("conversation").get()

    如果您期望 Firestore 仅返回规则计算结果为 true 的对话,那么这是行不通的。 Firestore 将发现某些对话文档不会评估为true并且整个查询将失败

    您需要确保您运行的导致规则评估的查询仅查看规则评估为 true 的对话,例如:

    firestore.collection("conversation").where(<some condition>).get()

    您可以在官方 Firestore 规则文档.

    回复
    0
  • 取消回复