【问题标题】:How do you properly order data from Firebase chronologically您如何正确地按时间顺序从 Firebase 中排序数据
【发布时间】:2016-09-05 18:09:21
【问题描述】:

我正在尝试从 Firebase 订购我的数据,因此最近的帖子位于顶部(如 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)
    })
}

【问题讨论】:

标签: ios swift firebase firebase-realtime-database


【解决方案1】:

仅对数组使用 reverse() 不足以包含所有内容。您需要考虑不同的事情:

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

  • 滚动触发将显示单元格方法加载

让我们开始吧。您可以为您的帖子创建一个孩子 timestampdate/time 是全球性的。为了提供 Instagram 秒,我建议您使用 UTC 时间。所以我称之为:(timeUTC)

要对所有帖子进行排序,请使用 since1970 时间戳。所以我将其称为 (timestamp),然后您也可以将另一个节点作为 (reversedTimestamp) 添加 - 前缀到时间戳。所以当你对这个节点使用 queryOrdered 时。您可以使用 yourQuery.queryLimited(toFirst: 5) 处理最新的 5 个帖子。

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 表示世界时间,看http://time.is/tr/UTC

2.获取 since1970 时间戳以在 Swift 3 中对帖子进行排序:

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"
    },

我将检索 5 到 5 个帖子,所以我在 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)
            })
        }
    })

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

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

   if self.posts.count - 1 == indexPath.row {
      // call loadMore function.
   }
}

在 loadMore() 函数中,您可以处理最新帖子的时间戳,然后像这样开始结束查询,因此您可以轻松地继续下一个前 5 个帖子,同时附加到数组之前。

对于 Swift 3 转换格式很好,请看这里:Swift 3 - UTC to time ago label, thinking 12h / 24h device time changes

【讨论】:

  • 非常感谢,这确实帮助并解决了我的问题。另外,我正在研究分页,所以太棒了!您必须使用单个事件进行分页吗?因为当新帖子提交时,它不会自动更新提要。
  • @kerbelda 我认为按降序观察每一个变化并不是我解释的正确方法。如果用户阅读了一个可以触发滚动的单元格,它会影响用户体验。如果您观察然后添加我的 tableView 数组,您会看到它无法正常工作。相反,您可以添加导航项以进行刷新(调用 viewDidLoad: 再次转到屏幕顶部)或在 scrollViewDidScroll() 中检查 self.tableView.contentOffset.y 等于 0 状态,然后您可以调用 viewDidLoad: 来自动加载最后 5 个帖子。
  • @tobeiosdev 你有我可以联系你的电子邮件吗?
【解决方案2】:

根据@tobeiosdev 的回答,我这样定义我的数据结构:

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

如您所见,我添加了一个时间戳属性,当我使用子添加事件查询我的数据时,我将该数据传递给一个帖子对象,然后我将该对象附加到我的表格视图中的帖子数组将喂:

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

通过排序方法,我设法按照帖子的期望顺序对我的数据进行排序,从最新到最旧。我希望这种方法可以帮助任何人:)。

【讨论】:

    猜你喜欢
    • 2017-05-10
    • 1970-01-01
    • 2017-07-20
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多