您如何按时间顺序正确地从 Firebase 订购数据
How do you properly order data from Firebase chronologically
我正在尝试从 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()来节省时间。您不需要每次都删除所有数组。
滚动触发器或将显示单元格方法加载
让我们开始吧。您可以为您的 posts timestamp 或 date/time 创建一个全局的 child。为了提供 Instagram 秒,我建议您使用 UTC 时间 周。所以我会这样称呼它:(timeUTC)
要对所有 post 进行排序,请使用 since1970 时间戳。所以我将调用它 (timestamp) 然后你也可以保留另一个节点作为 (reversedTimestamp) 添加 - 时间戳前缀。所以当你对这个节点使用queryOrdered的时候。您可以使用 with yourQuery.queryLimited(toFirst: 5)
.
处理最新的 5 post
1.Get UTC date/time for timeUTC node in Swift 3:
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.Get since1970 时间戳排序 posts in Swift 3:
let timestamp = (Date().timeIntervalSince1970 as NSString).doubleValue
let reversedTimestamp = -1.0 * timestamp
现在,您可以像这样将它们保存在您的 Firebase post 中。
"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"
},
我将按五个检索五个 post,所以我在 queryLimited(toFirst: 5) in viewDidLoad
:
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 时间戳,然后 start-end 查询,这样您就可以轻松地继续接下来的前 5 post 秒附加在数组之前。
For Swift 3 conversion as nice formatted, take a look here:
基于@tobeiosdev 的回答,我这样定义我的数据结构:
"posts" : {
"-KcOa8GXBl08V-WXeX8P" : {
"author" : "@giovanny.piñeros",
"hashtags" : [ "Hello", "World" ],
"text" : "Hola Mundo!!!!!",
"timestamp" : 5.08180914309278E8,
"title" : "Hello World",
"userid" : "hmIWbmQhfgh93"
}
如您所见,我添加了一个时间戳属性,当我使用添加的子事件查询我的数据时,我将该数据传递给一个 post 对象,然后将该对象附加到一个数组post 我的 table 视图将从中获取:
self.posts.append(post)
self.posts.sort(by: {[=11=].timestamp! > .timestamp!})
self.tableViewFeed.reloadData()
使用排序方法,我设法按照 post 的期望顺序对我的数据进行排序,从最新到最旧。我希望这种方法可以帮助任何人 :)。
我正在尝试从 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()来节省时间。您不需要每次都删除所有数组。
滚动触发器或将显示单元格方法加载
让我们开始吧。您可以为您的 posts timestamp 或 date/time 创建一个全局的 child。为了提供 Instagram 秒,我建议您使用 UTC 时间 周。所以我会这样称呼它:(timeUTC)
要对所有 post 进行排序,请使用 since1970 时间戳。所以我将调用它 (timestamp) 然后你也可以保留另一个节点作为 (reversedTimestamp) 添加 - 时间戳前缀。所以当你对这个节点使用queryOrdered的时候。您可以使用 with yourQuery.queryLimited(toFirst: 5)
.
1.Get UTC date/time for timeUTC node in Swift 3:
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.Get since1970 时间戳排序 posts in Swift 3:
let timestamp = (Date().timeIntervalSince1970 as NSString).doubleValue
let reversedTimestamp = -1.0 * timestamp
现在,您可以像这样将它们保存在您的 Firebase post 中。
"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"
},
我将按五个检索五个 post,所以我在 queryLimited(toFirst: 5) in viewDidLoad
:
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 时间戳,然后 start-end 查询,这样您就可以轻松地继续接下来的前 5 post 秒附加在数组之前。
For Swift 3 conversion as nice formatted, take a look here:
基于@tobeiosdev 的回答,我这样定义我的数据结构:
"posts" : {
"-KcOa8GXBl08V-WXeX8P" : {
"author" : "@giovanny.piñeros",
"hashtags" : [ "Hello", "World" ],
"text" : "Hola Mundo!!!!!",
"timestamp" : 5.08180914309278E8,
"title" : "Hello World",
"userid" : "hmIWbmQhfgh93"
}
如您所见,我添加了一个时间戳属性,当我使用添加的子事件查询我的数据时,我将该数据传递给一个 post 对象,然后将该对象附加到一个数组post 我的 table 视图将从中获取:
self.posts.append(post)
self.posts.sort(by: {[=11=].timestamp! > .timestamp!})
self.tableViewFeed.reloadData()
使用排序方法,我设法按照 post 的期望顺序对我的数据进行排序,从最新到最旧。我希望这种方法可以帮助任何人 :)。