Reputation: 433
Problem
I'm trying to query a list of objects by createionDate. For some reason it will not fetch objects in a ascending order.
My data structure
my code
func fetchQuest() {
guard let uid = selectedUID else {return}
let ref = FIRDatabase.database().reference().child("questsByUID").child(uid)
let query = ref.queryOrdered(byChild: "CreationDate")
query.observeSingleEvent(of: .value, with: { (snapshot) in
guard let dictionaries = snapshot.value as? [String: Any] else {return}
dictionaries.forEach({ (key, value) in
guard let dictionary = value as? [String : Any] else {return}
let quest = Quest(uid: uid, dictionary: dictionary)
quest.questID = key
print("quest name is: ", quest.questName)
self.board.append(quest)
})
self.collectionView?.reloadData()
}) { (err) in
print("unable to fetch quest:", err)
}
}
My Model
class Quest {
var questID = ""
let questName: String
let creatorUID: String
let creationDate: Date
init(uid: String, dictionary: [String: Any]) {
self.questName = dictionary["questName"] as? String ?? ""
self.creatorUID = uid
let secondsFrom1970 = dictionary["creationDate"] as? Double ?? 0
self.creationDate = Date(timeIntervalSince1970: secondsFrom1970)
}}
console output
quest name is: Third quest
quest name is: 2nd quest
quest name is: 4th quest from Ada
quest name is: Ada’s first quest
Upvotes: 2
Views: 2503
Reputation: 19339
Given that the Firebase database is case sensitive, try changing your query from:
let query = ref.queryOrdered(byChild: "CreationDate")
to:
let query = ref.queryOrdered(byChild: "creationDate")
Your Quest
model class is already using the correct spelling.
Update. As mentioned by the other answer, a dictionary is not order preserving. As such, you should be using FIRDataSnapshot.children
iterator instead. For instance:
query.observeSingleEvent(of: .value) {
(snapshots) in
for child in snapshots.children {
let snapshot = child as! DataSnapshot
guard let dictionary = snapshot.value as? [String : Any] else { return }
let quest = Quest(uid: uid, dictionary: dictionary)
quest.questID = snapshot.key
...
}
}
Please note that I'm still using the same observeSingleEvent
as your original code does.
Upvotes: 3
Reputation: 3606
I think order is different because dictionary is an unordered collection of key-value pairs. So I think since you want to get the values in ordered manner, you can use eventType of .childAdded
because according to documentation :
Unlike value which returns the entire contents of the location, childAdded is triggered once for each existing child and then again every time a new child is added to the specified path
so you can modify your code like this:
First as the other answer states that change CreationDate
to creationDate
Second use .childAdded
instead of .value
as the event type.
let query = ref.queryOrdered(byChild: "creationDate")
query.observe(.childAdded, with: { (snapshot) in...
Upvotes: 1