[英]How do you properly order data from Firebase chronologically
I'm trying to order my data from Firebase so the most recent post is at the top (like Instagram), but I just can't get it to work properly. 我正在尝试从Firebase订购我的数据,因此最新的帖子位于顶部(如Instagram),但我无法让它正常工作。 Should I be using a server timestamp?
我应该使用服务器时间戳吗? Is there a "createdAt" field?
是否有“createdAt”字段?
func getPosts() {
POST_REF.observeEventType(.Value, withBlock: { snapshot in
guard let posts = snapshot.value as? [String : [String : String]] else {
print("No Posts Found")
return
}
Post.feed?.removeAll()
for (postID, post) in posts {
let newPost = Post.initWithPostID(postID, postDict: post)!
Post.feed?.append(newPost)
}
Post.feed? = (Post.feed?.reverse())!
self.tableView.reloadData()
}, withCancelBlock: { error in
print(error.localizedDescription)
})
}
Using only reverse() for your array is not enough way to encompass everything. 仅对数组使用reverse()不足以涵盖所有内容。 There are different things you need to think about:
您需要考虑以下不同的事情:
Limit while retrieving data, use append() and then reverse() to save time. 在检索数据时限制,使用append()然后reverse()来节省时间。 You don't need to delete all array for each time.
您不需要每次都删除所有数组。
Scroll trigger or willDisplay cell method loading 滚动触发器或willDisplay单元格方法加载
Let's start. 开始吧。 You can create a child for your posts timestamp or date/time being global.
您可以为帖子时间戳或全局日期/时间创建子项。 To provide like Instagram seconds, weeks I advice you using UTC time .
为了提供类似Instagram的几秒钟,我建议你使用UTC时间 。 So I will call this: ( timeUTC )
所以我会这样称呼:( timeUTC )
For sorting your all post, use since1970 timestamp. 要对所有帖子进行排序,请使用自1970年以来的时间戳。 So I will call this ( timestamp ) and then also you can keep another node as (reversedTimestamp) adding - prefix to timestamp.
因此,我将调用此( 时间戳 ),然后您还可以将另一个节点作为(reversedTimestamp)添加 - 前缀到时间戳。 So when you use queryOrdered to this node.
所以当你对这个节点使用queryOrdered时。 You can handle latest 5 post using with
yourQuery.queryLimited(toFirst: 5)
. 您可以使用
yourQuery.queryLimited(toFirst: 5)
处理最新的5个帖子。
1.Get UTC date/time for timeUTC node in Swift 3: 1.获取Swift 3中timeUTC节点的UTC日期/时间:
let date = Date()
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
formatter.timeZone = TimeZone(abbreviation: "UTC")
let utcTimeZoneStr = formatter.string(from: date)
+0000 means it's universal time, look at http://time.is/tr/UTC +0000意味着它是世界时,请看http://time.is/tr/UTC
2.Get since1970 timestamp to sort posts in Swift 3: 2.获取自1970年时间戳以对Swift 3中的帖子进行排序:
let timestamp = (Date().timeIntervalSince1970 as NSString).doubleValue
let reversedTimestamp = -1.0 * timestamp
Now, you can save them on your Firebase posts like this. 现在,您可以将它们保存在Firebase帖子上。
"posts" : {
"-KHLOy5mOSq0SeB7GBXv" : {
"timestamp": "1475858019.2306"
"timeUTC" : "2012-02-04 12:11:56 +0000"
},
"-KHLrapS0wbjqPP5ZSUY" : {
"timestamp": "1475858010.1245"
"timeUTC" : "2014-02-04 12:11:56 +0000"
},
I will retrieve five by five post, so I'm doing queryLimited(toFirst: 5) in viewDidLoad
: 我将检索五个五个帖子,所以我在
viewDidLoad
执行queryLimited(toFirst:5) :
let yourQuery = ...queryOrdered(byChild: "reverseTimestamp")
.queryEnding(atValue: "\(self.pageOnTimestamp)", childKey: "reverseTimestamp")
yourQuery.observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.value is NSNull {
print("There is no post.")
}
else {
yourQuery.queryLimited(toFirst: 5).observeSingleEvent(of: .value, with: { (snapshot) in
self.posts.removeAll(keepingCapacity: true)
for (i, snap) in snapshot.children.enumerated() {
if let postAllDict = snapshot.value as? [String: AnyObject] {
if let postDict = postAllDict[(snap as AnyObject).key as String] as? [String: AnyObject] {
let post = Post(key: (snap as AnyObject).key as String, postDict: postDict)
self.posts.append(post)
}
}
}
completion(true)
})
}
})
If user reached latest post, you can handle it with willDisplay
method like below, then you can call loadMore function. 如果用户到达最新帖子,您可以使用如下所示的
willDisplay
方法处理它,然后您可以调用loadMore函数。
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if self.posts.count - 1 == indexPath.row {
// call loadMore function.
}
}
In loadMore() function you can handle latest post's timestamp, then start-end query as with that, so you can easily continue with next first 5 posts while appending before array. 在loadMore()函数中,您可以处理最新帖子的时间戳,然后是开始结束查询,这样您就可以轻松地继续下一个前5个帖子,同时在数组之前附加。
For Swift 3 conversion as nice formatted, take a look here: Swift 3 - UTC to time ago label, thinking 12h / 24h device time changes
对于格式良好的Swift 3转换,请看一下: Swift 3 - UTC时间标签,思考12h / 24h设备时间变化
Based on @tobeiosdev answer i define my data structure like this: 根据@tobeiosdev的答案我定义我的数据结构如下:
"posts" : {
"-KcOa8GXBl08V-WXeX8P" : {
"author" : "@giovanny.piñeros",
"hashtags" : [ "Hello", "World" ],
"text" : "Hola Mundo!!!!!",
"timestamp" : 5.08180914309278E8,
"title" : "Hello World",
"userid" : "hmIWbmQhfgh93"
}
As you can see i've added a timestamp attribute, when i query my data with a child added event, i pass that data to a post object, then i append that object to an array of posts from which my table view will feed: 正如您所看到的,我添加了一个timestamp属性,当我使用子添加事件查询我的数据时,我将该数据传递给post对象,然后我将该对象附加到我的表视图将从中提供的帖子数组:
self.posts.append(post)
self.posts.sort(by: {$0.timestamp! > $1.timestamp!})
self.tableViewFeed.reloadData()
With the sort method i've managed to order my data in the desire order of posts, from the newest to the oldest. 通过排序方法,我设法按照从最新到最旧的帖子的期望顺序来排序我的数据。 I Hope this approach could help anyone :).
我希望这种方法可以帮助任何人:)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.