Swift 2017
I'd like to present an as elegant solution as i could made for this task of pagination with the firebase. This method called both when initializing and loading more data:
var items: [ItemEntity] = []
var theEndOfResults = false
var lastLoadedItem: ItemEntity? {
return items.last
}
func loadItems() {
let isLoadingMore = lastLoadedItem != nil
Decorator.showStatusBarLoader()
self.databaseReference
.child("items")
.queryOrdered(byChild: "date")
.queryEnding(atValue: isLoadingMore ? lastLoadedItem!.date.stringValue : Date.distantFuture.stringValue)
.queryLimited(toLast: 5)
.observeSingleEvent(of: .value) { snapshot in
var items = self.array(from: snapshot)
.map { ItemEntity(parentKey: $0.parentKey, dictionary: $0.dict) }
self.theEndOfResults = (self.lastLoadedItem == items.last) // prevent loading when it's no more items
if isLoadingMore { items.removeFirst() } // removing as the firebase sending a repeated one
self.items.append(contentsOf: items)
self.reloadData()
}
}
The function for reloading data in controller.
override func reloadData() {
tableV.reloadData()
refreshControl.endRefreshing()
tableV.loadControl?.endLoading()
Decorator.hideStatusBarLoader()
}
This is called when a user reach the end of tableView.
@objc public func loadMore() {
guard self.theEndOfResults == false else { tableV.loadControl?.endLoading(); return }
self..loadItems()
}
Making array from snapshot
func array(from snapshot: DataSnapshot) -> [ParseResult] {
var items = [ParseResult]()
if let snapshots = snapshot.children.allObjects as? [DataSnapshot] {
for snap in snapshots {
if let postDictionary = snap.value as? Dictionary<String, AnyObject> {
items.append((snap.key, postDictionary))
}
}
}
print(" DATA COME:\r\(snapshot)")
//or u can use: dump(items, indent: 2, maxDepth: 5, maxItems: 15)
return items.reversed()
}
Thanks this video for clarifying some moments with "cool" firebase reference api.
Good luck in development and ask any questions if found something unclear.