Reputation: 427
I try to load the posts I stored on firebase into my tableView. I used the .childAdded function to get the post in the order they have been posted (first to last). First it seemed to work, but now it doesn't work no more and I don't know why. So I added a timestamp to the posts and used queryOrderedByChild("timestamp"). Still the wrong order though! Here is my code:
posts.removeAll()
let ref = FIRDatabase.database().reference()
ref.child("Posts").queryOrderedByChild("timestamp").observeEventType(.ChildAdded, withBlock: { (snapshot:FIRDataSnapshot) in
print(snapshot.value!["timestamp"] as! Int)
if snapshot.value == nil {
return
}
let post = Post()
post.title = snapshot.value!["Title"] as? String
post.postType = snapshot.value!["postType"] as? Int
post.postDescription = snapshot.value!["Description"] as? String
if post.postType == 2 {
post.imageAURL = snapshot.value!["imageAURL"] as? String
post.imageBURL = snapshot.value!["imageBURL"] as? String
}else if post.postType == 3 {
post.imageAURL = snapshot.value!["imageAURL"] as? String
post.imageBURL = snapshot.value!["imageBURL"] as? String
post.imageCURL = snapshot.value!["imageCURL"] as? String
}
let createdByID = snapshot.value!["createdBy"] as! String
var username = String()
let usernameRef = FIRDatabase.database().reference().child("users").child(createdByID)
usernameRef.observeSingleEventOfType(.Value, withBlock: { (snapshot:FIRDataSnapshot) in
username = snapshot.value!["username"] as! String
post.createdBy = username
self.posts.append(post)
self.tableView.reloadData()
}, withCancelBlock: nil)
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
}, withCancelBlock: nil)
}
the print of the timestamp value in the beginning of the query puts out:
1471008028
1471007899
1471007928
1471007979
As you can see, the first Int is the highest, the next three are ordered correctly in ascending order, but why is the highest first and not last? I don't know if it has anything to do with it, but the code is inside a function that is called inside viewDidLoad.
Upvotes: 2
Views: 1744
Reputation: 58440
There is an existing answer that explains why Firebase JavaScript child_added
events occur out-of-order. It is still applicable and is the reason why your snapshots are being delivered in an unexpected order.
I know this may seem strange, but this is actually the intended behavior.
In order to guarantee that local events can fire immediately without communicating with the server first, Firebase makes no guarantees that child_added events will always be called in sort order.
To arrange the received snapshots into the correct order, you need the previous sibling key that accompanies the snapshot (it's referred to as the prevChildName
in the referenced answer). To obtain the previous sibling key, you need to use observeEventType:andPreviousSiblingKeyWithBlock:
.
The Firebase documentation for observeEventType:andPreviousSiblingKeyWithBlock:
does not make it clear how the previous sibling key ought to be used to arrange the received snapshots.
For the purposes of an example, to store and order the snapshots in an array, you would need to do the following for each received a snapshot:
Upvotes: 1