Firebase aucun index défini

J'utilise Firebase pour récupérer des données d'utilisateurs. Je dois récupérer un seul Utilisateur avec ( gameSearching = true ).

Mes données ressemblent à:

 Users | |_____ John | |___ name: John Farmer | |___ gameSearching: true | |_____ James | |___ name: James Smith | |___ gameSearching: false | |_____ Barbara |___ name: Barbara Smith |___ gameSearching: true 

J'utilise ce code:

 setData(('Users/' + you + '/'), {gameSearching: true}); var ref = new Firebase("https://grootproject.firebaseio.com/Users"); var child = ref.orderByChild("gameSearching"); child.on("child_added", function (data) { var yourself = firebase.getAuth().password.email.split("@", 1)[0]; data.forEach( function (childSnapshot) { if (childSnapshot[i].val().gameSearching == true && childSnapshot[i].key() != yourself) { var opponent = childSnapshot[i].key(); setData(('Users/' + opponent + '/'), {gameSearching: false}); setData(('Users/' + yourself + '/'), {gameSearching: false}); } } ); }); 

Parce que 'data' a plusieurs valeurs, j'utilise 'data.forEach' pour les séparer. Après ce point, je peux définir un «retour» sur «vrai», donc je ne recevrai qu'un Utilisateur avec «GameSearching: true».

Mes règles de la base de feu:

 { "rules": { ".read": true, ".write": true, ".indexOn": "gameSearching" } } 

Lorsque je lance ce code, j'ai l'erreur suivante:

'Erreur non détectée: aucun index défini pour la recherche de jeu'

J'ai cherché à définir un index sur 'GameSearching' en utilisant '.indexOn' mais pas avec succès. Https://www.firebase.com/docs/security/guide/indexing-data.html

Quelqu'un at-il un exemple ou une solution?


Modifier:

J'ai maintenant le code suivant:

 var ref = new Firebase("https://grootproject.firebaseio.com/Users"); ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1).on("child_added", function (data) { var yourself = firebase.getAuth().password.email.split("@", 1)[0]; var opponent = data.key(); console.log(opponent); setData(('Users/' + opponent + '/'), {gameSearching: false}); setData(('Users/' + yourself + '/'), {gameSearching: false}); console.log('ja'); }); 

J'ai édité mes règles de ma base de travail:

 { "rules": { ".read": true, ".write": true, "Users": { ".indexOn": "gameSearching" } } 

}

L'erreur d'indexOn ne montrera plus, donc c'est génial. Mais ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1 ) s'exécutera deux fois. Je ne sais pas comment cela est possible. J'utilise limitToFirst (1) `, donc j'attends 1 enfant?

Maintenant que vous avez ajouté vos règles, il est clair ce qui ne va pas.

Voici vos règles actuelles:

 { "rules": { ".read": true, ".write": true, ".indexOn": "gameSearching" } } 

Donc, vous permettez à tous de lire et d'écrire sur votre base de données intégrale et de lui dire d'ajouter un index sur gameSearching . Le problème est que vous avez défini votre index au niveau supérieur, au lieu d'être au niveau où il doit être dans votre base Firebase.

Voici votre structure de données actuelle:

 { "Score" : { "sam_lous" : { "score" : 2 } }, "Users" : { "hallo" : { "gameSearching" : true }, "sam_lous" : { "gameSearching" : true }, "test" : { "gameSearching" : false }, "test2" : { "gameSearching" : true } } } 

La propriété gameSearching existe uniquement sous les enfants du nœud Users . C'est donc là que vous devez définir votre .indexOn :

 { "rules": { ".read": true, ".write": true, "Users": { ".indexOn": "gameSearching" } } } 

Avec cela, votre index devrait être créé (dans mon expérience, il se produit tout de suite lorsque vous enregistrez vos règles) et que le message d'erreur / avertissement doit disparaître. Mais pour corriger le comportement, vous devriez également apporter les modifications que j'ai apportées dans mon autre réponse.

Je dois admettre que la documentation de Firebase sur l'indexation de vos données pourrait être plus claire sur l'endroit où vous définissez ces règles .indexOn . Si quelqu'un à Firebase lit en lecture, pouvez-vous ajouter quelques exemples qui soulignent que .indexOn doit être défini au niveau où réside la donnée?

Votre requête commande les données, mais ne parvient pas à la filtrer. Si vous le modifiez, la requête ne correspond que aux utilisateurs qui recherchent un jeu:

 var query = ref.orderByChild("gameSearching").equalTo(true); 

Cela se traduit approximativement par un SQL de WHERE gameSearching = true , c'est ce que vous avez posé dans votre question précédente. Notez que j'ai appelé la query variable, car elle représente une requête sur les données. Ou si vous souhaitez adhérer aux métaphores SQL, il est plus similaire à un VIEW dans une base de données relationnelle.

Comme vous écoutez child_added votre fonction sera invoquée une fois pour chaque utilisateur qui correspond à votre requête. Donc, pour forEach cela, forEach n'a aucun sens pour moi dans votre extrait. Si vous souhaitez utiliser un pour forEach vous pouvez obtenir tous les utilisateurs qui correspondent à la requête à la fois avec l'événement de value :

 var searchers = ref.orderByChild("gameSearching").equalTo(true); searchers.on('value', function(searchersSnapshot) { searchersSnapshot.forEach(function(snapshot) { console.log(snapshot.key()); }); }); 

Ce qui enregistrera actuellement cette connexion sur votre Firebase:

Bonjour

Sam_lous

Test2

Vous pouvez également utiliser child_added pour accomplir la même chose, mais dans ce cas, vous n'avez pas besoin pour forEach :

 var searchers = ref.orderByChild("gameSearching").equalTo(true); searchers.on('child_added', function(snapshot) { console.log(snapshot.key()); }); 

Un fait amusant: en cours on('child_added' déclenche le Firebase AVERTISSEMENT d'un index manquant, on('value' ne l'est pas. Mais de toute façon: vous devriez vraiment ajouter l'index, car sans cette performance ne sera pas acceptable lorsque vous ajouterez des joueurs.

Puisque vous indiquez que vous avez besoin d'un seul enfant, vous pouvez également limiter la requête pour vous donner le premier enfant:

 var searchers = ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1); 

Ces et bien d'autres opérations sont couvertes aux sections 2 à 5 du Guide Web Firebase .