web-dev-qa-db-fra.com

Ajout et ".indexOn": ".value" dans les règles Firebase

J'étudie AngularJS et Firebase et je joue avec un ChatApp simple, juste pour comprendre le code.

Ma structure Firebase DB est comme ceci:

"chat": {
    "messages": {
        "chat1": { [ list of messages ] },
        "chat2": { [ list of messages ] }
    },
    "rooms": {
        "chat1": {
            "users": {
                "user1": true,
                "user2": true
            }
        },
        "chat2": {
            "users": {
                "user2": true,
                "user3": true
            }
        }
    }
}

En raison des règles de protection Firebase, je ne peux pas ajouter de lien de discussion dans le nœud utilisateur, alors je dois faire une requête Firebase pour récupérer les salles de discussion pour l'utilisateur, en utilisant la requête orderByChild() au démarrage de l'application.

L'utilisation de Firebase est plus simple que je ne peux récupérer tous les chats en utilisant:

var chatLink = firebase.database().ref('chat/rooms');
chatLink
  .orderByChild('users/' + userId)
  .equalTo(true)
  .once('value', function(chatSnap){

      /* Do Some Stuff Here */

  });

Tout fonctionne bien, mais je reçois un avertissement dans la console:

AVERTISSEMENT DE LA BASE DE FEU: Utilisation d'un index non spécifié. Pensez à ajouter ".indexOn": "users/{userId}" dans/chat/rooms à vos règles de sécurité pour de meilleures performances

En recherchant sur le Web, j'ai trouvé que pour la variable orderByChild() requête, je peux utiliser .indexOn: .value Dans mes règles Firebase.

J'ai essayé d'ajouter cette règle:

{
    "rules": {
        "chat": {
            "rooms": {
                ".indexOn": ".value"
            }
        }
    }
}

Mais je reçois toujours cet avertissement. Comment puis-je le réparer?

Merci beaucoup!

12
Marco Cavanna

Pour indexer cette structure pour permettre une interrogation efficace, vous devez ajouter un index pour chaque utilisateur:

{
    "rules": {
        "chat": {
            "rooms": {
                ".indexOn": ["users/user1", "users/user2"]
            }
        }
    }
}

Cela ne sera pas maintenable, car vous ajoutez probablement des utilisateurs de manière dynamique.

Comme d'habitude avec les bases de données NoSQL, cela signifie que vous devez étendre/adapter votre modèle de données pour permettre le cas d'utilisation que vous souhaitez. Au lieu d'interroger les chambres pour leurs utilisateurs, conservez une liste des chambres pour chaque utilisateur (en plus de vos données actuelles):

"user_rooms": {
  "user1": {
    "chat1": true
  },
  "user2": {
    "chat1": true,
    "chat2": true
  }
  "user3": {
    "chat2": true
  }

Vous pouvez maintenant rechercher les salles de chat d'un utilisateur sans même avoir à interroger.

Voir également ma réponse à propos de ce problème de catégorisation dans requête Firebase si l'enfant de l'enfant contient une valeur .

12

Je sais que cela peut être un peu en retard, mais voici quelque chose qui peut vous aider. Je cherchais les mêmes informations que vous, et dans mon cas, elles m'ont écouté.

$ usersId correspond à n'importe quelle clé enfant. Vous devez donc faire quelque chose comme ça.

{
"rules": {
     "chat": {
         "rooms": {
             "users": {
                 "$usersId": {
                    ".indexOn": ".value"
                }
            }
        }
    }
}

Mon cas: en utilisant un index non spécifié. Pensez à ajouter '".indexOn": "date"' dans messages/-L2bPVX4_fL41H7lhexc à vos règles de sécurité et de base de données Firebase pour de meilleures performances

L2bPVX4_fL41H7lhexc == enfant dans ma structure de base de données NoSQL

solution:

"messages": {
  "$messagesId": {
    ".indexOn": "date"
  }
}
8
DawidJ