Firebase快照顺序错误

我尝试将我在firebase中存储的post加载到我的tableView中。 我使用.childAdded函数按发布顺序(首先到最后)获取post。 首先它似乎工作,但现在它不再工作,我不知道为什么。 所以我给post添加了一个时间戳,并使用queryOrderedByChild(“timestamp”)。 依然错误的顺序! 这是我的代码:

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) } 

查询开头的时间戳值打印出来:

 1471008028 1471007899 1471007928 1471007979 

正如你所看到的,第一个Int是最高的,接下来的三个是按升序正确排列的,但是为什么是最高的而不是最后的呢? 我不知道它是否与它有任何关系,但代码是在viewDidLoad内调用的函数。

现有的答案解释了为什么Firebase JavaScript child_added事件child_added发生。 它仍然适用,并且是您的快照以意外顺序传递的原因。

我知道这可能看起来很奇怪,但这实际上是预期的行为。

为了确保本地事件可以在不与服务器通信的情况下立即触发,Firebase不保证child_added事件总是按sorting顺序调用。

要按照正确的顺序排列接收到的快照,您需要提供快照的前一个兄弟密钥(在引用的答案中称为prevChildName )。 要获得以前的同级密钥,您需要使用observeEventType:andPreviousSiblingKeyWithBlock:

observeEventType:andPreviousSiblingKeyWithBlock:的Firebase文档没有清楚说明应该如何使用以前的兄弟密钥排列接收到的快照。

出于示例的目的,要将快照存储并sorting在数组中,您需要为每个接收到的快照执行以下操作:

  • 如果收到的快照有一个空的前兄弟密钥,将它添加到数组的头部;
  • 否则,在数组中find具有与之前的兄弟密钥相同的密钥的快照(伴随着收到的快照),并在find的快照之后将所接收的快照插入到数组中;
  • 如果前面的兄弟关键字没有快照,则将接收到的快照添加到数组的尾部。