J'essaie d'interroger ma base de données de telle sorte qu'elle récupère une liste ordonnée basée sur une clé enfant. Je le fais comme suit (voir ci-dessous), mais rien ne se produit, ce qui signifie qu'il renvoie un objet commandé exactement de la même manière qu'il est stocké dans la base de données Firebase. Que se passe-t-il?
self.getAllProfiles = function () {
var qProfile = $q.defer();
var ref = new Firebase(FBURL);
ref.child("users").orderByChild('last_update').on("value", function (snapshot) {
console.log(snapshot.val()) // HERE IS WHERE IT SHOULD BE ORDERED
qProfile.resolve(snapshot.val());
}, function (errorObject) {
qProfile.reject(errorObject);
});
return qProfile.promise;
};
Pour ajouter, mon noeud utilisateurs ressemble à ceci:
users
/$username
/last_update
/id
/data
/profile_image
/display_name
Voici un aperçu:
Tester: Object
github: Object
last_update: 1447732462170
userId: "github:12345"
Lorsque vous appelez snapshot.val()
, vous récupérez un objet JSON. L'ordre des clés dans un objet JSON est déterminé par votre navigateur et non par Firebase.
Pour mettre les enfants en ordre:
self.getAllProfiles = function () {
var qProfile = $q.defer();
var ref = new Firebase(FBURL);
ref.child("users").orderByChild('last_update').on("value", function (snapshot) {
snapshot.forEach(function(child) {
console.log(child.val()) // NOW THE CHILDREN PRINT IN ORDER
});
qProfile.resolve(snapshot.val());
}, function (errorObject) {
qProfile.reject(errorObject);
});
return qProfile.promise;
};
Vous pouvez laisser l'appel q.resolve()
tel qu'il est: snapshot.forEach()
n'est pas un appel asynchrone.
Je sais que cette question a été répondue et a plus d'un an, mais comme il y a encore une certaine confusion dans la section commentaire, j'aimerais ajouter quelques informations.
Le problème initial est que l'OP souhaite récupérer une liste ordonnée basée sur une clé enfant de la base de données en temps réel Firebase, mais la fonction .orderByChild('arg')
ne fonctionne pas comme prévu.
Mais ce qui n'a pas fonctionné comme prévu n'est pas .orderByChild('arg')
, mais .on("value", callback)
. Parce que .on("value", callback)
fonctionne un peu différemment des autres eventTypes comme .on("child_added", callback)
.
Disons que nous avons une base de données en temps réel firebase comme ci-dessous:
{
myData: {
-KYNMmYHrzLcL-OVGiTU: {
NO: 1,
image: ...
},
-KYNMwNIz4ObdKJ7AGAL: {
NO: 2,
image: ...
},
-KYNNEDkLpuwqQHSEGhw: {
NO: 3,
image: ...
},
}
}
-
Si nous utilisons .on("value", callback)
, le callback () sera appelé 1 fois et retournera un tableau d'objets de 3 objets.
ref.on("value", function(snapshot) {
console.log(snapshot.val());
// Please see Frank van Puffelen's answer
}
-
Si nous utilisons .on("child_added", callback)
, le callback () sera appelé 3 fois, à chaque fois retourne un objet, et ils sont retournés dans l'ordre.
ref.once("child_added", function(snapshot) {
console.log(snapshot.val());
// The objects are returned in order, do whatever you like
}
Si vous avez seulement besoin d'extraire les données ordonnées de firebase (par exemple, pour initialiser l'interface utilisateur), alors ref.orderByChild('arg').once("child_added", callback)
vous ira bien, c'est simple et facile à utiliser.
Cependant, si pour une raison quelconque vous devez utiliser ref.orderByChild('arg').on("value", callback)
, veuillez vous reporter à la réponse de Frank van Puffelen.
Veuillez lire Document Firebase pour plus d’informations sur on(eventType, callback, cancelCallbackOrContext, context)
, leurs arguments et leurs valeurs de retour.
Autre document utile: Travailler avec des listes de données sur le Web
Pour commander à l'aide de l'écouteur d'événements value
:
firebase.database().ref('/invoices').orderByChild('name').on('value', snapshot => {
snapshot.forEach(child => {
console.log(child.key, child.val());
});
}
Si vous voulez inverser l'ordre, essayez:
function reverseSnapshotOrder (snapshot) {
let reversed = [];
snapshot.forEach(child => {
reversed.unshift(child);
});
return reversed;
}
reverseSnapshotOrder(snapshot).forEach(child => {
console.log(child.key, child.val());
});
Veuillez consulter: https://firebase.google.com/docs/database/web/lists-of-data#listen_for_value_events
Je me suis battu avec le même problème dans iOS. Si vous convertissez un instantané en objet NSDictionary, celui-ci est converti en liste non ordonnée. Version Objective-c en cas de besoin:
[[self.refChild queryOrderedByChild:@"date_created"]
observeEventType:FIRDataEventTypeValue
withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
for (FIRDataSnapshot *child in snapshot.children) {
NSDictionary *anObject = child.value;
NSString *aKey = child.key;
}
}];