Firebase快照顺序错误 [英] Firebase snapshots in wrong order

查看:185
本文介绍了Firebase快照顺序错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

pre $ post $ $ $ $ b $ ref let FIRDatabase.database()。reference()在

打印(快照。)中使用的察看事件类型(.ChildAdded,withBlock:{(snapshot:FIRDataSnapshot))

ref.child(Posts)。queryOrderedByChild(timestamp value![timestamp] as!Int)
if $ snapshot $ value $ = snapshot.value![Title] as?String
post.postType = snapshot.value![postType] as?Int
post.postDescription = snapshot.value![Description] as?String

如果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![imageB URL]为?字符串
post.imageCURL = snapshot.value![imageCURL] as?字符串
}


让createdByID = snapshot.value![createdBy] as! String
var username = String()
let usernameRef = FIRDatabase.database()。reference()。child(users)。child(createdByID)
usernameRef.observeSingleEventOfType(.Value, withBlock:$(
$ b $ username = snapshot.value![username] as!String
post.createdBy = username $ b $ self.posts.append(











$ dispatch_async(dispatch_get_main_queue(),{

self.tableView.reloadData()
})


},withCancelBlock:nil)


}

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

  1471008028 
1471007899
1471007928
1471007979

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

p>现在有一个答案,它解释了为什么Firebase JavaScript child_added 事件发生无序。它仍然适用,并且是您的快照以意想不到的顺序交付的原因。


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

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

要将接收到的快照按照正确的顺序排列,您需要提供伴随快照的上一个兄弟关键字(它被称为作为参考答案中的 prevChildName )。要获取之前的兄弟关键字,您需要使用 observeEventType:andPreviousSiblingKeyWithBlock:


$ b

Firebase文档 observeEventType:andPreviousSiblingKeyWithBlock: code>并没有清楚说明应该如何使用前面的兄弟密钥来安排接收的快照。



为了举例说明,在数组中对快照进行排序,您需要为每个接收到的快照执行以下操作:


  • 如果接收到的快照的前一个为null兄弟关键字,将其添加到数组的头部;否则,请在数组中找到具有 key 等于前面的兄弟关键字(包括收到的快照),并在找到的快照之后将接收到的快照插入到数组中;
  • 如果没有使用之前的兄弟密钥创建快照,将接收到的快照添加到数组尾部。


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.

解决方案

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:

  • if the received snapshot has a null previous sibling key, add it to the head of the array;
  • otherwise, find the snapshot in the array that has a key equal to the previous sibling key (that accompanied the recieved snapshot) and insert the received snapshot into the array after the found snapshot;
  • if there is no snapshot with the previous sibling key, add the received snapshot to the tail of the array.

这篇关于Firebase快照顺序错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆