我尝试将存储在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中调用的函数内。
答案 0 :(得分:0)
现有answer解释了为什么Firebase JavaScript child_added
事件无序发生的原因。它仍然适用,是您以意想不到的顺序交付快照的原因。
我知道这可能看起来很奇怪,但实际上这是预期的行为。
为了保证本地事件无需先与服务器通信即可立即触发,Firebase不保证始终按排序顺序调用child_added事件。
要按照正确的顺序排列收到的快照,您需要快照附带的上一个同级密钥(在引用的答案中称为prevChildName
)。要获取上一个兄弟键,您需要使用observeEventType:andPreviousSiblingKeyWithBlock:
。
observeEventType:andPreviousSiblingKeyWithBlock:
的Firebase文档未明确说明应如何使用上一个兄弟键来安排收到的快照。
出于示例的目的,要在数组中存储和排序快照,您需要为每个接收到的快照执行以下操作: