您如何正确地从Firebase按时间顺序sorting数据

我试图从Firebase订购我的数据,所以最近的post是在顶部(如Instagram),但我不能让它正常工作。 我应该使用服务器时间戳吗? 有没有“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) }) } 

只使用reverse()为你的数组是不够的方法来包容一切。 有不同的事情你需要考虑:

  • 限制检索数据时,使用append() ,然后使用reverse()来节省时间。 您不需要每次都删除所有数组。

  • 滚动触发器willDisplay单元格方法加载

开始吧。 您可以创build一个孩子为您的post时间戳date/时间是全球性的。 要提供像Instagram秒,几周我build议你使用UTC时间 。 所以我会打电话给这个:( timeUTC

为了sorting你所有的post,使用自1970年以来的时间戳。 所以我会调用这个( 时间戳 ),然后还可以保留另一个节点为(reversedTimestamp)添加 – 时间戳的前缀。 所以当你使用queryOrdered到这个节点。 您可以使用yourQuery.queryLimited(toFirst: 5)处理最新的5篇文章。

1.获取Swift 3中timeUTC节点的UTCdate/时间:

  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意味着它是世界时,请看http://time.is/tr/UTC

2.自从1970年以来在Swift 3中对post进行sorting的时间戳:

 let timestamp = (Date().timeIntervalSince1970 as NSString).doubleValue let reversedTimestamp = -1.0 * timestamp 

现在,您可以将它们保存在您的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" }, 

我会检索五个五,所以我在做viewLidLoad 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) }) } }) 

如果用户达到最新的post,你可以用下面的willDisplay方法处理它,然后你可以调用loadMore函数。

 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { if self.posts.count - 1 == indexPath.row { // call loadMore function. } } 

在loadMore()函数中,你可以处理最新的post的时间戳,然后开始 – 结束查询,所以你可以轻松地继续下一个前5个职位,同时追加数组。

对于Swift 3格式化好的转换,请看看这里: Swift 3 – UTC到前一个标签,思考12h / 24h设备时间变化

基于@tobeiosdev答案我定义我的数据结构是这样的:

 "posts" : { "-KcOa8GXBl08V-WXeX8P" : { "author" : "@giovanny.piñeros", "hashtags" : [ "Hello", "World" ], "text" : "Hola Mundo!!!!!", "timestamp" : 5.08180914309278E8, "title" : "Hello World", "userid" : "hmIWbmQhfgh93" } 

正如你可以看到我已经添加了一个timestamp属性,当我查询我的数据与一个孩子添加事件,我把这些数据传递到一个后对象,然后我将该对象追加到我的表视图将提供的post数组:

  self.posts.append(post) self.posts.sort(by: {$0.timestamp! > $1.timestamp!}) self.tableViewFeed.reloadData() 

使用sorting方法,我已经按照从最新到最旧的post的期望顺序来sorting我的数据。 我希望这种方法可以帮助任何人:)。