Reputation: 445
I'm trying to paginate posts that users are following to my collection view from my firebase database. Currently only 4 posts are being appended to the collection view and not loading anymore when I scroll down.
I've tried changing the number of posts loaded initially with no luck.
fileprivate func fetchFollowingUserIds() {
guard let uid = Auth.auth().currentUser?.uid else { return }
Database.database().reference().child("user-following").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
guard let userIdsDictionary = snapshot.value as? [String: Any] else { return }
userIdsDictionary.forEach({ (key, value) in
Database.fetchUserWithUID(uid: key, completion: { (user) in
self.fetchPostsWithUser(user: user)
})
})
}) { (err) in
print("Failed to fetch following user ids:", err)
}
}
var posts = [Post]()
fileprivate func fetchPosts() {
guard let uid = Auth.auth().currentUser?.uid else { return }
Database.fetchUserWithUID(uid: uid) { (user) in
self.fetchPostsWithUser(user: user)
}
}
var isFinishedPaging = false
fileprivate func fetchPostsWithUser(user: User) {
self.collectionView?.refreshControl?.endRefreshing()
let ref = Database.database().reference().child("posts").child(user.uid)
var query = ref.queryOrdered(byChild: "creationDate")
if posts.count > 0 {
let value = posts.last?.creationDate.timeIntervalSince1970
query = query.queryEnding(atValue: value)
}
query.queryLimited(toLast: 4).observeSingleEvent(of: .value, with: { (snapshot) in
guard var allObjects = snapshot.children.allObjects as? [DataSnapshot] else { return }
allObjects.reverse()
if allObjects.count < 4 {
self.isFinishedPaging = true
} else {
self.isFinishedPaging = false
}
if self.posts.count > 0 && allObjects.count > 0 {
allObjects.removeFirst()
}
allObjects.forEach({ (snapshot) in
guard let dictionary = snapshot.value as? [String: Any] else { return }
var post = Post(user: user, dictionary: dictionary)
post.id = snapshot.key
self.posts.append(post)
})
self.collectionView?.reloadData()
}) { (err) in
print(err)
}
}
I simply want it to load more posts when the user scrolls down.
Upvotes: 1
Views: 116
Reputation: 35658
There may be a query issue or a potential logic issue. Lets assume you want to present posts to the user, with the most recent at the top of the list and allow the user to scroll down to see earlier posts.
Let's address both with an example:
We don't have your structure but keeping it super simple, suppose your posts have the following structure with creation dates
post_0
creation_date: "20180101"
post_1
creation_date: "20180102"
post_2
creation_date: "20180103"
post_3
creation_date: "20180104"
post_4
creation_date: "20180105"
post_5
creation_date: "20180106"
post_6
creation_date: "20180107"
post_7
creation_date: "20180108"
Here's your initial query, order by creation date, which will load the last 4 posts from the 5th to the 8th
var query = ref.queryOrdered(byChild: "creationDate")
Then subsequent queries are ordered by creation date but the ending value is not the creation date but the time elapsed since 1970 of the creation date.
let value = posts.last?.creationDate.timeIntervalSince1970
var query = ref.queryOrdered(byChild: "creationDate").queryEnding(atValue: value)
I would guess you just want to load the next 4 earlier posts. So as this sit in the array, they look like this:
20180108
20180107
20180106
20180105
One way to do that is the get the creationDate of the last post from your dataSource (which will be the oldest post)
20180105
Then query by creationDate, endingAt the creation date of the last post, getting 5 total posts, then remove the last one
20180101
20180102
20180103
20180104
20180105
then reversed
20180105
20180104
20180103
20180102
20180101
and remove the first
20180104
20180103
20180102
20180101
something like this
let lastD = self.postsArray.last
self.postsArray = []
let postsRef = self.ref.child("posts")
let queryRef = postsRef.queryOrdered(byChild: "creation_date")
let queryEndingRef = queryRef.queryEnding(atValue: lastD)
let queryLimitedRef = queryEndingRef.queryLimited(toLast: 5)
queryLimitedRef.observeSingleEvent(of: .value, with: { snapshot in
guard var thisArray = snapshot.children.allObjects as? [DataSnapshot] else { return }
thisArray.reverse()
thisArray.removeFirst()
for post in thisArray {
let theDate = post.childSnapshot(forPath: "creation_date").value as! String
self.postsArray.append(theDate)
}
})
Upvotes: 2