Méthode Firebase queryOrderedByChild () ne donnant pas de données sortingées

Salut ma structure de database est quelque chose comme ça

{ "users": { "alovelace": { "name": "Ada Lovelace", "score": 4, }, "ghopper": { ... }, "eclarke": { ... } } } 

J'essaie de récupérer les 20 meilleurs scores dans l'ordre décroissant.

 let queryRef = FIRDatabase.database().reference().child("users").queryOrderedByChild("score").queryLimitedToLast(20) queryRef.observeSingleEventOfType(.Value, withBlock: { (quearySnapShot) in print(quearySnapShot.value) }) 

J'essaie d'get des résultats comme

 score": 4 score": 3 score": 2 or score": 2 score": 3 score": 4 or 2 3 4 

S'il vous plaît laissez-moi savoir comment résoudre ce problème.

Utilisez la méthode observeEventType au lieu de observeSingleEventOfType . Créez également FIRDataEventType à ChildAdded .

Enfin, si vous souhaitez utiliser les 20 premiers éléments, utilisez queryLimitedToFirst au lieu de queryLimitedToLast .

 { "users" : { "alovelace" : { "name" : "Ada Lovelace", "score" : 4 }, "eclarke" : { "name" : "Emily Clarke", "score" : 5 }, "ghopper" : { "name" : "Grace Hopper", "score" : 2 } } } 

Pour l'set de données ci-dessus

 let queryRef = FIRDatabase.database().reference().child("users").queryOrderedByChild("score").queryLimitedToFirst(20) queryRef.observeEventType(.ChildAdded, withBlock: { (snapshot) in print("key: \(snapshot.key), value: \(snapshot.value)") }) 

key: ghopper, valeur: Facultatif ({name = Grace Hopper, score = 2;})

key: alovelace, valeur: Facultatif ({name = Ada Lovelace; score = 4;})

key: eclarke, valeur: Facultatif ({name = Emily Clarke, score = 5;})

Snapshot renvoie le contenu en tant que types natifs. Types de données renvoyés:

  • NSDictionary
  • NSArray
  • NSNumber (inclut également les booleans)
  • NSSsortingng

Donc, vous pouvez get vos scores de cette façon.

  let queryRef = FIRDatabase.database().reference().child("users").queryOrderedByChild("score").queryLimitedToFirst(20) queryRef.observeEventType(.ChildAdded, withBlock: { (snapshot) in if let scores = snapshot.value as? NSDictionary { print(scores["score"]) } }) 

Facultatif (2)

En option (4)

Facultatif (5)

De plus, la database en time réel par défaut returnne tout dans l' ordre croissant .

Si vous voulez un ordre décroissant , vous pouvez faire quelques astuces (4:40) dans votre database.

Lorsque vous requestz les enfants dans un ordre spécifique, l'instantané résultant contiendra à la fois datatables qui correspondent à la requête et les informations sur l'ordre dans lequel vous les avez demandées.

Mais lorsque vous requestz le .value de l'instantané, les keys + données sont converties en un Dictionary<Ssortingng,AnyObject> . Comme un dictionary ne dispose pas d'un location supplémentaire pour mettre les informations sur la command, cette information est perdue lors de la conversion en dictionary.

La solution est de ne pas convertir prématurément en dictionary et de faire plutôt une boucle sur l'instantané:

 queryRef.observeSingleEventOfType(.Value, withBlock: { (querySnapShot) in for childSnapshot in querySnapShot.children { print(childSnapshot.value) } }) 

Vous pouvez également écouter l'événement .ChildAdded , au lieu de .Value , auquel cas les enfants arriveront avec la valeur correcte:

 queryRef.observeSingleEventOfType(.ChildAdded, withBlock: { (childSnapshot) in print(childSnapshot.value) }) 

Mettre à jour

Je viens d'append ce JSON à ma database:

 { "users" : { "alovelace" : { "name" : "Ada Lovelace", "score" : 4 }, "eclarke" : { "name" : "Emily Clarke", "score" : 5 }, "ghopper" : { "name" : "Grace Hopper", "score" : 2 } } } 

Et puis couru ce code:

 let queryRef = ref.child("users").queryOrderedByChild("score").queryLimitedToLast(20); queryRef.observeEventType(.ChildAdded) { (snapshot) in print(snapshot.key) } 

La sortie est:

ghopper

alovelace

eclarke

Quels sont les users dans l'ordre croissant du score.

Mise à jour pour en append plus sur l'obtention des scores par ordre décroissant

Le code ci-dessus obtient les 20 meilleurs scores dans l'ordre croissant. Il n'y a pas d'appel d'API pour les renvoyer dans le score décroissant.

Mais inverser 20 éléments côté client n'est pas une question de performance, il vous suffit d'écrire le code pour cela. Voir par exemple cette réponse .

Si vous êtes vraiment bloqué en inversant le côté client, vous pouvez append un score inversé. Voir cette réponse pour un exemple de cela.