Firebase快照的顺序错误

时间:2016-08-12 13:38:12

标签: ios database swift firebase firebase-realtime-database

我尝试将存储在firebase上的帖子加载到我的tableView中。我使用.childAdded函数按照发布的顺序(从头到尾)获取帖子。首先它似乎工作,但现在它不再工作,我不知道为什么。所以我在帖子中添加了一个时间戳,并使用了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中调用的函数内。

1 个答案:

答案 0 :(得分:0)

现有answer解释了为什么Firebase JavaScript child_added事件无序发生的原因。它仍然适用,是您以意想不到的顺序交付快照的原因。

  

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

     

为了保证本地事件无需先与服务器通信即可立即触发,Firebase不保证始终按排序顺序调用child_added事件。

要按照正确的顺序排列收到的快照,您需要快照附带的上一个同级密钥(在引用的答案中称为prevChildName)。要获取上一个兄弟键,您需要使用observeEventType:andPreviousSiblingKeyWithBlock:

observeEventType:andPreviousSiblingKeyWithBlock:的Firebase文档未明确说明应如何使用上一个兄弟键来安排收到的快照。

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

  • 如果收到的快照具有空的上一个兄弟键,则将其添加到数组的头部;
  • 否则,在数组中查找key等于上一个兄弟密钥(附带快照的快照)的快照,并在找到的快照后将接收到的快照插入到数组中;
  • 如果上一个兄弟键没有快照,请将收到的快照添加到阵列的尾部。