web-dev-qa-db-fra.com

Comment interroger Firebase pour une propriété avec une valeur spécifique dans tous les enfants

J'ai cette structure de données, où les todos sont organisés pour suivre le chemin/todos/uid /

{
  "metausers" : {
    "simplelogin:1" : {
      "displayName" : "John Doe",
      "provider" : "password",
      "provider_id" : "1"
    },
    "simplelogin:2" : {
      "displayName" : "GI Jane",
      "provider" : "password",
      "provider_id" : "2"
    }
  },
  "todos" : {
    "simplelogin:1" : {
      "-JUAfv4_-ZUlH7JqM4WZ" : {
        "completed" : false,
        "done" : false,
        "group" : false,
        "private" : false,
        "subject" : "First"
      },
      "-JUAfveXP_sqqX32jCJS" : {
        "completed" : false,
        "done" : false,
        "group" : false,
        "private" : true,
        "subject" : "Second"
      },
      "-JUAfwXnMo6P53Qz6Fd2" : {
        "completed" : false,
        "done" : false,
        "group" : false,
        "private" : false,
        "subject" : "Third"
      }
    },
    "simplelogin:2" : {
      "-JUAg9rVemiNQykfvvHs" : {
        "completed" : false,
        "done" : false,
        "group" : false,
        "private" : false,
        "subject" : "Q first"
      },
      "-JUAgAmgPwZLPr2iH1Ho" : {
        "completed" : false,
        "done" : false,
        "group" : false,
        "private" : false,
        "subject" : "Q second"
      },
      "-JUAgBfF8f7V5R5-XgrY" : {
        "completed" : false,
        "done" : false,
        "group" : false,
        "private" : true,
        "subject" : "Q third"
      }
    }
  }
}

et je voudrais interroger todos pour obtenir tous les enregistrements avec private:true. Est-ce possible avec Firebase (angularfire) et comment dois-je le faire? Ou devrais-je dénormaliser un peu plus et organiser le chemin/privé pour éviter de marcher sur todos?

36
Denis

Il n'y a pas de clauses WHERE dans Firebase. Consultez ce fil pour quelques bons conseils structurels sur la recherche par plusieurs champs, ce fil sur les requêtes de style de base de données, ce blog sur les requêtes, et - les docs .

Votre première approche devrait être de segmenter les données en fonction de leur lecture. Quelque chose comme ceci:

/todos/public
/todos/private
/todos/completed

Vous pouvez également tiliser les priorités comme expliqué dans la documentation. Récupérez ensuite les éléments en fonction de la priorité.

Si la liste est inférieure à mille, ce qui devrait être le cas si les données sont correctement partitionnées, vous pouvez probablement simplement saisir la liste des tâches et la filtrer également sur le client - une excellente option pour les collections courtes comme celle-ci, en particulier lorsque vous travaillez avec une grande lib reliure comme Angular.

17
Kato

En supposant que vous ayez l'uid, cela devrait être simple avec ce qui suit:

var uid = "simplelogin:1";
var todosRef = new Firebase("https://yourdb.firebaseio.com/todos/" + uid);
var privateTodosRef = todosRef.orderByChild("private").equalTo(true);
var privateTodos;

privateTodosRef.on("value", function(response) {
  privateTodos = response.val();
});

Cela devrait renvoyer un objet avec toutes les tâches privées de cet utilisateur, organisées par leur clé de tâche (c'est-à-dire "-JUAfv4_-ZUlH7JqM4WZ". Si vous souhaitez utiliser Angularfire, vous pouvez envelopper cela dans un $ firebaseArray et l'affecter comme suit:

$scope.privateTodos = $firebaseArray(privateTodosRef);

Voici ne référence pour plus d'informations sur les requêtes complexes, et comme mentionné dans les autres réponses, il y a quelques belles optimisations qui peuvent être faites avec les priorités et la restructuration.

Bon codage!

55
Matt

Toutes les données de Firebaase sont accessibles par URL. Si vous accédez à votre tableau de bord Firebase pour afficher votre modèle de données (Forge) et cliquez sur la propriété qui vous intéresse, vous serez redirigé vers une URL par laquelle vous pouvez accéder à ces données particulières, par exemple https://myapp.firebaseio.com/todos/simplelogin:1/-JUAg9rVemiNQykfvvHs/private . Gardant cela à l'esprit, vous pouvez accéder à ces données avec AngularFire.

3