我尝试将存储在 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 内部调用的函数内。
有一个现有的answer https://stackoverflow.com/a/15723418/6680611这解释了为什么 Firebase JavaScriptchild_added
事件发生无序。它仍然适用,也是您的快照以意外顺序交付的原因。
我知道这可能看起来很奇怪,但这实际上是预期的行为。
为了保证本地事件可以立即触发而无需先与服务器通信,Firebase 不保证 child_added 事件始终按排序顺序调用。
要将收到的快照按正确的顺序排列,您需要快照附带的前一个同级密钥(称为prevChildName
在引用的答案中)。要获取前一个同级密钥,您需要使用observeEventType:andPreviousSiblingKeyWithBlock: https://firebase.google.com/docs/reference/ios/firebasedatabase/interface_f_i_r_database_query.html#a206825e56f8ab6803b1764feec51cd45.
Firebase 文档observeEventType:andPreviousSiblingKeyWithBlock:
没有明确说明如何使用前一个同级密钥来排列接收到的快照。
出于示例目的,要在阵列中存储和排序快照,您需要对每个收到的快照执行以下操作:
- 如果接收到的快照的前一个兄弟键为空,则将其添加到数组的头部;
- 否则,在阵列中查找具有key https://firebase.google.com/docs/reference/ios/firebasedatabase/interface_f_i_r_data_snapshot.html#a84dcc624075720e171f27b8e9ee8c678等于前一个同级键(伴随收到的快照)并将收到的快照插入到数组中找到的快照之后;
- 如果不存在具有前一个兄弟键的快照,则将接收到的快照添加到数组的尾部。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)