web-dev-qa-db-fra.com

Règles de sécurité Firestore: recherche de l'ID d'un utilisateur dans un tableau dans un document

Tout d'abord, désolé pour mon terrible anglais, ce n'est pas ma langue maternelle ...

Je crée une application simple dans Firebase, en utilisant la base de données Firestore. Dans mon application, les utilisateurs sont membres de petits groupes. Ils ont accès aux données des autres utilisateurs. Afin de ne pas interroger trop de documents (un par utilisateur, dans une sous-collection du document du groupe), j'ai choisi d'ajouter les données des utilisateurs dans un tableau à l'intérieur du document du groupe. Voici le document de mon groupe:

{
   "name":"fefefefe",
   "days":[false,false,false,false,true],
   "members":[
       {"email":"[email protected]","id":"aaaaaaaa","name":"Mavireck"}, 
       {"email":"[email protected]","id":"bbbbbbbb","name":"Mavireck2"}, 
   ],
}

Comment puis-je vérifier avec les règles de sécurité si un utilisateur est dans un groupe? Dois-je utiliser un objet à la place? Je préférerais vraiment ne pas utiliser de sous-collection pour les utilisateurs, car j'atteindrais les limites du quota gratuit trop rapidement ...

Merci pour votre temps !

EDIT: Merci pour la réponse. Je vais le changer en un objet: "Members": {uid1: {}, uid2: {}}

21
Mavireck

En général, vous devez écrire une règle comme celle-ci:

service cloud.firestore {
  match /databases/{database}/documents {
    match /collection/{documentId} {
      // works if `members` = [uid1, uid2, uid3]
      // no way to iterate over a collection and check members
      allow read: if request.auth.uid in resource.data.members;
      // you could also have `members` = {uid1: {}, uid2: {}}
      allow read: if resource.data.members[request.auth.uid] != null;
    }
  }
}

Vous pouvez également utiliser des sous-collections:

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow a user to read a message if the user is in the room
    match /rooms/{roomId} {
      match /documents/{documentId} {
        allow read: if exists(/databases/$(database)/documents/documents/$(documentId)/users/$(request.auth.uid));
      }
      match /users/{userId} {
        // rules to allow users to operate on a document
      }
    }
  }
}
22
Mike McDonald

Je l'ai fait avec ce code

Autoriser certains utilisateurs à lire/écrire certains documents d'une collection si ce même utilisateur est présent dans un tableau d'une autre collection

service cloud.firestore {
  match /databases/{database}/documents {
    match /repositories/{accountId} {
      allow read, write: if request.auth.uid in get(/databases/$(database)/documents/accounts/$(accountId)).data.users
    }
  }
}
13
calebeaires