I am working on my pagination feature and so far was able to paginate posts by timestamp. The issue is in the version I use (from a course) that it queries posts depending on its value always starting from a value a bit higher than before which works fine when using timestamp as the numbers are really high and more likely to differ. Now I want to do the pagination stuff with my posts ordered by likeCount. The issue now is that as there are many posts/comments with equal likes the pagination doesnt work properly anymore.
Here Is my code
func observeAllPostsForTrendByLikeCount(start likeCount: Int? = nil, limit: UInt, completionHandler: @escaping ([(Post, UserModel)]) -> Void) {
var postQuery = REF_POST.queryOrdered(byChild: "likeCount")
if let latestPostLikeCount = likeCount, latestPostLikeCount >= 0 {
postQuery = postQuery.queryStarting(atValue: latestPostLikeCount + 1, childKey: "likeCount").queryLimited(toLast: limit)
} else {
postQuery = postQuery.queryLimited(toLast: limit)
}
postQuery.observeSingleEvent(of: .value, with: { (snapshot) in
let items = snapshot.children.allObjects
let myGroup = DispatchGroup()
var results: [(post: Post, user: UserModel)] = []
for (index, item) in (items as! [DataSnapshot]).enumerated() {
myGroup.enter()
API.Post.observePost(withId: item.key, completion: { (post) in
API.User.observeUser(withId: post.userId!, completion: { (user) in
results.insert((post, user), at: index)
myGroup.leave()
})
})
}
myGroup.notify(queue: .main) {
results.sort(by: {$0.0.likeCount! > $1.0.likeCount!})
completionHandler(results)
}
})
}
func loadMoreTrendByLikeCount(start likeCount: Int, limit: UInt, completionHandler: @escaping ([(Post, UserModel)]) -> Void) {
let postOrderedQuery = REF_POST.queryOrdered(byChild: "likeCount")
let postLimitedQuery = postOrderedQuery.queryEnding(atValue: likeCount , childKey: "likeCount").queryLimited(toLast: limit)
postLimitedQuery.observeSingleEvent(of: .value, with: { (snapshot) in
let items = snapshot.children.allObjects
let myGroup = DispatchGroup()
var results = [(post: Post, user: UserModel)]()
for (index, item) in (items as! [DataSnapshot]).enumerated() {
myGroup.enter()
API.Post.observePost(withId: item.key, completion: { (post) in
API.User.observeUser(withId: post.userId!, completion: { (user) in
results.insert((post, user), at: index)
myGroup.leave()
})
})
}
myGroup.notify(queue: .main) {
results.sort(by: {$0.0.likeCount! > $1.0.likeCount! })
completionHandler(results)
}
})
}
This code works fine as long as the posts have different like counts but as I scroll deeper and face multiply posts with 0 likes it doesn't load further.
here is how I fetch the posts
func loadTrendByLikeCount() {
isLoadingPost = true
API.Post.observeAllPostsForTrendByLikeCount(start: posts.first?.likeCount, limit: 3) { (results) in
if results.count > 0 {
results.forEach({ (result) in
if self.segmentedControl.selectedSegmentIndex == 1 {
self.posts.append(result.0)
self.users.append(result.1)
}
})
}
self.isLoadingPost = false
if self.refreshControl.isRefreshing {
self.refreshControl.endRefreshing()
}
self.activityIndicatorView.stopAnimating()
self.tableView.reloadData()
}
}
and the scroll method
if scrollView.contentOffset.y >= scrollView.contentSize.height - self.view.frame.size.height {
guard !isLoadingPost else {
return
}
isLoadingPost = true
guard let lastPostLikeCount = self.posts.last?.likeCount else {
isLoadingPost = false
return
}
self.Indicator.startAnimating()
API.Post.loadMoreTrendByLikeCount start: lastPostLikeCount, limit: 4) { (results) in
if results.count == 0 {
self.Indicator.stopAnimating()
return
}
for result in results {
if !self.posts.contains(where: {$0.id == result.0.id}) {
self.posts.append(result.0)
self.users.append(result.1)
}
}
self.tableView.reloadData()
self.Indicator.stopAnimating()
self.isLoadingPost = false
}
}
As I said this works and loads more post as long as not too many posts are at the same likecount. Moreover the loadMore() function ends in an infinity loop...
Thanks in advance