Reputation: 3100
When I load the following Firebase Database data into my tableView, the data is sorted in ascending order by date. How can I order this by descending (show the newest post at the top)?
Query in Xcode:
let ref = self.rootRef.child("posts").queryOrderedByChild("date").observeEventType(.ChildAdded, withBlock: { (snapshot) -> Void in
JSON export:
"posts" : {
"-KMFYKt7rmfZINetx1hF" : {
"date" : "07/09/16 12:46 PM",
"postedBy" : "sJUCytVIWmX7CgmrypqNai8vGBg2",
"status" : "test"
},
"-KMFYZeJmgvmnqZ4OhT_" : {
"date" : "07/09/16 12:47 PM",
"postedBy" : "sJUCytVIWmX7CgmrypqNai8vGBg2",
"status" : "test"
},
Thanks!!
EDIT: Below code is the entire solution thanks to Bawpotter
Updated query:
let ref = self.rootRef.child("posts").queryOrderedByChild("date").observeEventType(.ChildAdded, withBlock: { (snapshot) -> Void in
let post = Post.init(key: snapshot.key, date: snapshot.value!["date"] as! String, postedBy: snapshot.value!["postedBy"] as! String, status: snapshot.value!["status"] as! String)
self.posts.append(post)
self.tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: self.posts.count-1, inSection: 0)], withRowAnimation: .Automatic)
tableView cellForRowAtIndexPath
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("PostCell", forIndexPath: indexPath) as! PostCell
self.posts.sortInPlace({$0.date > $1.date})
self.tableView.reloadData()
Post.swift:
import UIKit
class Post {
var key: String
var date: String
var postedBy: String
var status: String
init(key: String, date: String, postedBy: String, status: String){
self.key = key
self.date = date
self.postedBy = postedBy
self.status = status
}
}
Upvotes: 3
Views: 13743
Reputation: 56
Swift 5: Add reversed() to your objects after sorting by the required field. For example, let's assume you have a day of the month in the "day" field in FireStore. Something like this will do the trick (call loadData() function in viewDidLoad to see the output):
let db = Firestore.firestore()
func loadData() {
db.collection("FireStoreCollectionName").order(by: "day").getDocuments { (querySnapshot, error) in
if let e = error {
print("There was an issue retrieving data from Firestore, \(e)")
} else {
for document in querySnapshot!.documents.reversed() {
let data = document.data()
let fDay = data["day"] as! Int
print(fDay)
}
}
}
}
Upvotes: 0
Reputation: 8568
.reverse()
before using datamyRef.observe(.value) { (snapshot) in
guard var objects = snapshot.children.allObjects as? [DataSnapshot] else {
return
}
objects.reverse() //<========= HERE
//Now use your `objects`
...
}
Upvotes: 2
Reputation: 1365
When Firebase loads the data into your tableView data source array, call this:
yourDataArray.sortInPlace({$0.date > $1.date})
Swift 3 Version:
yourDataArray.sort({$0.date > $1.date})
Swift 4 Version:
yourDataArray.sort(by: {$0.date > $1.date})
Upvotes: 12
Reputation: 157
While I do recommend doing what was posted and creating a Class and doing it that way, I will give you another way to do sort it.
Since you already have it sorted in Ascending order from Firebase and you know the amount of records, you can do this:
guard let value = snapshot.children.allObjects as? [FIRDataSnapshot] else {
return
}
var valueSorted: [FIRDataSnapshot] = [FIRDataSnapshot]()
var i: Int = value.count
while i > 0 {
i = i - 1
valueSorted.append(value[i])
}
Upvotes: 1