Votre structure de données est grande de chercher les participants à un salon de discussion particulier. Il n'est toutefois pas une très bonne structure pour la recherche de l'inverse: les chats que l'utilisateur participe à.
Quelques problèmes ici:
- vous êtes le stockage d'un ensemble , comme un tableau
- vous pouvez seulement l'index sur les chemins
Jeu vs tableau
Un chat peut avoir plusieurs participants, de sorte que vous modelé cette comme un tableau. Mais en fait, ce n'est pas l'idéal structure de données. Probablement chaque participant ne peut être dans le chat une fois. Mais en utilisant un tableau, j'ai pu avoir:
participants: ["puf", "puf"]
C'est clairement pas ce que vous avez à l'esprit, mais la structure de données permet. Vous pouvez essayer d'obtenir ce dans le code et les règles de sécurité, mais il serait plus facile si vous commencez avec une structure de données qui, implicitement correspond à votre modèle mieux.
Ma règle d'or: si vous vous retrouvez à écrire array.contains()
, vous devriez être en utilisant un ensemble.
Un ensemble est une structure où chaque enfant peut être présent dans la plupart des une fois, de sorte qu'il protège naturellement contre les doublons. Dans Firebase vous auriez un modèle fixé comme suit:
participants: {
"puf": true
}
L' true
ici, c'est vraiment juste une valeur factice: l'important, c'est que nous avons adopté le nom de la clé. Maintenant, si je devais essayer de rejoindre ce chat, il serait un noop:
participants: {
"puf": true
}
Et quand tu allais rejoindre:
participants: {
"john": true,
"puf": true
}
C'est le plus direct de la représentation de votre exigence: une collection qui ne peut contenir que chaque participant une fois.
Vous pouvez seulement de l'indice de propriétés connues
Avec la structure ci-dessus, vous pourriez requête pour les chats que vous êtes, avec:
ref.child("chats").orderByChild("participants/john").equalTo(true)
Le problème est que ce besoin de vous définir un index sur les "participants/john":
{
"rules": {
"chats": {
"$chatid": {
"participants": {
".indexOn": ["john", "puf"]
}
}
}
}
}
Cela permettra de travailler et d'effectuer des grands. Mais maintenant, à chaque fois que quelqu'un de nouveau se joint à l'application de chat, vous aurez besoin d'ajouter un autre indice. C'est clairement pas une évolutive modèle. Nous allons devoir changer notre structure de données pour permettre à la requête que vous souhaitez.
Inverser l'indice - pull catégories jusqu', l'aplatissement de l'arbre
Deuxième règle de base: le modèle de vos données afin de refléter ce que vous montrez dans votre application.
Puisque vous êtes à la recherche pour afficher la liste des salles de chat pour un utilisateur, de stocker les salles de chat pour chaque utilisateur:
userChatrooms: {
john: {
chatRoom1: true,
chatRoom2: true
},
puf: {
chatRoom1: true,
chatRoom3: true
}
}
Maintenant, vous pouvez tout simplement déterminer votre liste de salles de tchat avec:
ref.child("userChatrooms").child("john")
Et puis une boucle sur les touches pour obtenir chaque chambre.
Vous aimerez avoir deux listes dans votre application:
- la liste des salles de chat pour un utilisateur spécifique
- la liste des participants dans une salle de chat
Dans ce cas, vous aurez également deux listes dans la base de données.
chatroomUsers
chatroom1
user1: true
user2: true
chatroom2
user1: true
user3: true
userChatrooms
user1:
chatroom1: true
chatroom2: true
user2:
chatroom1: true
user2:
chatroom2: true
J'ai tiré les deux listes de haut-niveau de l'arbre, depuis Firebase recommande à l'encontre de l'imbrication des données.
Avoir deux listes est tout à fait normal dans les solutions NoSQL. Dans l'exemple ci-dessus, nous aurions reportez-vous à l' userChatrooms
comme l'index inversé de chatroomsUsers
.
Cloud Firestore
C'est un des cas où le Cloud Firestore a un meilleur support pour ce type de requête. Ses array-contains
de l'opérateur permet de filtrer les documents qui ont une certaine valeur dans un tableau, alors que arrayRemove
permet de traiter un tableau comme un ensemble. Pour en savoir plus, voir Mieux Tableaux dans le Cloud Firestore.