Les règles Firestore refusent toute demande de discussion avec des applications avec des collections imbriquées. Qu'ai-je fait de mal?
P粉627136450
P粉627136450 2023-09-08 15:04:01
0
1
536

Je suis actuellement en train de créer une application de chat et j'ai des problèmes avec les règles Firebase. Je souhaite empêcher les utilisateurs de voir les conversations dont ils ne font pas partie. Cependant, lorsque j'essaie de mettre en œuvre ces règles, l'accès semble être refusé même après avoir vérifié si la conversation existe. Comment configurer correctement les règles Firebase pour permettre aux utilisateurs d'afficher uniquement les conversations dont ils font partie, plutôt que toutes les conversations de la base de données ?

C'est l'ensemble de règles que j'essaie de mettre en œuvre uniquement pour les conversations.

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));
    }
  }
}

L'accès a été refusé au "haut niveau", c'est ça :

// 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));
    }

Je pense que cela a quelque chose à voir avec la façon dont fonctionnent ces conversations imbriquées, mais je ne sais pas ce que je dois changer. J'ai essayé de lire à ce sujet dans la documentation de Google Firebase, mais je n'ai rien trouvé à ce sujet. Si vous avez des idées sur la façon de résoudre ce problème, faites-le-moi savoir. Merci!

J'ai essayé de le faire fonctionner avec plusieurs "ensembles de règles". Il échoue toujours avec la fonction exist().

J'ai aussi essayé ceci mais cela ne semble pas fonctionner non plus :

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);
      }
    }
  }
}

Voici la requête que j'utilise dans 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粉627136450
P粉627136450

répondre à tous(1)
P粉459578805

Vous n'avez pas partagé la requête que vous exécutiez et qui a déclenché cet échec, mais il est important de se rappeler que Les règles Firestore ne sont pas des filtres .

Si votre requête ressemble à ceci :

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

Si vous vous attendez à ce que Firestore ne renvoie que des règles évaluées à true 的对话,那么这是行不通的。 Firestore 将发现某些对话文档不会评估为trueet la requête entière échouera.

Vous devez vous assurer que la requête que vous exécutez et qui entraîne l'évaluation de la règle ne s'intéresse qu'aux conversations pour lesquelles la règle est évaluée comme vraie, par exemple :

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

Vous pouvez le trouver dans le document officiel des règles Firestore中了解更多信息>.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal