Mon objectif:
L'application Web (similaire à Google Drive) dispose de 2 écrans.
Le premier écran est «Mon histoire» qui affiche tous les documents d'histoire dont je suis le propriétaire.
Le deuxième écran est «Partagé avec moi» qui affiche tous les documents d'histoire que je Je suis soit un lecteur, un écrivain ou un commentateur.
Nous avons ce /stories/{storyid}
db .collection('stories') .where(`roles.${uid}`, '==', 'owner')
Données complètes référence de la structure: https://firebase.google.com/docs/firestore/ solutions / accès basé sur les rôles
Question: Comment écrire la requête ci-dessous pour atteindre l'objectif ci-dessus?
{ title: "A Great Story", content: "Once upon a time ...", roles: { alice: "owner", bob: "reader", david: "writer", jane: "commenter" // ... } }
La requête ci-dessus ne fonctionne PAS car elle obligera Firestore à indexer les rôles.alice, roles.bob, roles.david, roles.jane et roles. [All_uid].
Modification n ° 1: Nous avons trouvé un message connexe (sans réponse) demandant à propos de Firestore interrogeant avec des rôles
p >
4 Réponses :
Vous ne pouvez pas réaliser cela avec votre structure de base de données actuelle sans avoir besoin de créer un index pour chaque utilisateur séparément. Pour résoudre ce problème, vous devez dupliquer vos données. Cette pratique s'appelle De plus, lorsque vous dupliquez des données, il y a une chose à garder à l'esprit. De la même manière que vous ajoutez des données, vous devez les maintenir. En d'autres termes, si vous voulez mettre à jour / dételer un élément, vous devez le faire dans tous les endroits où il existe. Cela étant dit, vous devez créer une autre collection nommée Donc, une requête comme celle-ci: fonctionnera parfaitement . dénormalisation
et est une pratique courante en ce qui concerne Firebase. Si vous êtes nouveau dans les bases de données NoQSL, je vous recommande de voir cette vidéo, La dénormalisation est normale avec la base de données Firebase pour une meilleure compréhension. C'est pour la base de données en temps réel Firebase, mais les mêmes règles s'appliquent à Cloud Firestore. userStories code >, où vous devez ajouter comme documents toutes les histoires dont un utilisateur est
propriétaire
. La structure de votre base de données devrait donc ressembler à ceci: db.collection('userStories').doc(${uid})
.collection('allStories').where(`role`, '==', 'owner');
Firestore-root
|
--- userStories (collection)
|
--- uid (document)
|
--- allStories (collection)
|
--- storyId
|
--- role: "owner"
pouvez-vous commenter ma réponse. Je pense connaître la réponse à ma question.
S'il vous plaît voir mon commentaire ci-dessus. Je vais donc m'en tenir à cette réponse.
Qu'est-ce qui vous motive à répondre aux questions sur le SO? Juste curieux. Google / Firebase vous paie-t-il pour chaque réponse réussie?
@ choopage-JekBao Non. J'ai aussi été aidé une fois et j'aimerais aider les autres de la même manière;)
Il n'est pas possible, par conséquent, nous devons dupliquer les données dans NoSQL.
Une structure de données possible est
/ stories / {storyid}
db .collection('stories') .where('shared', 'array_contains', uid)
Nous pouvons donc interroger l'interface utilisateur de l'application Web "Mon histoire"
db .collection('stories') .where('owner', '==', uid)
Alors que nous pouvons rechercher l'interface utilisateur de l'application Web "Partagé avec me '
{ title: "A Great Story", content: "Once upon a time ...", roles: { alice: "owner", bob: "reader", david: "writer", jane: "commenter", mary: "writer", // ... }, owner: "alice", // newly added shared: ["bob", "david", "jane", "mary"] // newly added // alice, bob, david, jane, mary are firebase auth uid }
La réponse est inspirée des commentaires de @Doug Stevenson.
@DougStevenson que pensez-vous de cette réponse?
Non, ce n'est pas une option puisque vous dupliquez des données dans le même document. Dans ce cas, qu'en est-il de la recherche de toutes les histoires jane == commenter
? Lorsque nous dupliquons des données, nous dupliquons le document entier, de sorte que nous pouvons copier exactement les mêmes données qui existent déjà à un endroit, à un autre, pour répondre à des requêtes qui ne seraient même pas possibles autrement. C'est exactement votre cas.
S'il vous plaît laissez-moi savoir si je me trompe, mais il semble que votre requête devrait fonctionner. à titre expérimental, j'ai ajouté la structure que vous avez donnée dans la question et effectué la requête avec succès dans la console Firebase.
N'est-ce pas ce que vous recherchez? Je me suis également assuré que l'opérateur "in" fonctionne également pour ce cas. De cette façon, vous pouvez demander quelles histoires l'utilisateur est le propriétaire et le commentateur.
Avez-vous un index là-dessus?
Non, rien de plus n'a été configuré pour que cela fonctionne. Cela fonctionne hors de la boîte dans cet exemple.
J'ai essayé cela mais je n'ai pas réussi à obtenir mes résultats!
c'est ce que je recherche.
Vous pouvez maintenant filtrer ...
db .collection('orders') .where('orderDetails.status', '==', 'OPEN')
Il vérifiera si le champ orderDetails de la propriété status est égal à "OPEN"
Le lien que vous avez fourni concerne la sécurité, pas les requêtes. Si vous souhaitez interroger ce document par utilisateur, vous devrez alors l'indexer par utilisateur. Vous pouvez également restructurer vos données afin de pouvoir interroger des documents d'une manière qui n'exige pas que le nom de l'utilisateur soit un champ dans le document.
Donc, fondamentalement, vous voulez obtenir toutes les histoires où
alice == propriétaire
, non?@AlexMamo Oui. Vous voulez obtenir toutes les histoires qui appartiennent à un UID (par exemple, Alice) qui est le propriétaire.
@DougStevenson Oui, le lien fourni concerne la sécurité. Cependant, le lien fait simplement référence à la structure de données fournie par votre équipe à titre d'exemple. En utilisant l'exemple de structure de données et en souhaitant effectuer des requêtes, il n'est pas logique d'indexer par utilisateur. Donc, s'il y a 1 000 000 d'utilisateurs, faut-il créer autant d'indices? En aucune façon! Alors, comment interroger des rôles dans un document qui peut renvoyer tous les documents appartenant à un user_id? par exemple. Alice.
Comme je l'ai dit, vous devrez utiliser une structure différente pour prendre en charge la requête que vous souhaitez effectuer. Il est courant dans les bases de données NoSQL de dupliquer des données pour différents besoins. Vous avez un besoin de sécurité, ce qui est bien. Vous avez maintenant un deuxième besoin, qui nécessite une deuxième solution.
@DougStevenson J'ai répondu à la question avec une réponse inspirée de votre commentaire. Pourriez-vous jeter un œil à la réponse et partager avec moi votre opinion?
@ choopage-JekBao Pouvez-vous expliquer comment la réponse acceptée a résolu ce problème? Merci