User Profile Pagination Part 2
Instagram Firebase
Let's continue with the Pagination lesson by looking at how we can page for data and sorting by the creationDate key of our Posts. In order to do this correctly, we'll be querying for data at the end of the list with queryLimited(toLast: Int) and collecting Post objects in reverse order. Once you're done with the video, I highly recommend walking through the logic yourself so that you understand the order in which objects are coming back.

Comments (50)
GeminixClown
6 years ago
How about if we post reversed creation date when we post some object to firebase, so we don't need reversed allObject?
Brian Voong
6 years ago
juliolocoh
6 years ago
Hey Brian we wanna learn more from it will be great if you show us to post videos in those round stories cells like in real Instagram thanks
Kenny Ho
6 years ago
Hey Brian, thank you for the new update! I noticed that for "Additional Lessons To Be Determined" it still asks me to sign in to leave a comment even though I'm already signed in. I don't know if maybe I signed up through Facebook is the cause of the problem. Anyways it's no problem, I'll just leave my request here. If its not too troubling, would you mind teaching us how to tag people in our photos? Similar to how Facebook and Instagram lets you tag your friends in the photo. Thank you! Best, Kenny
faisalmlalani
6 years ago
Hey Brian, great video, as always. I recently found out about collection view prefetching (https://www.youtube.com/watch?v=4e7Kt23lZUU) and was wondering if it would be a good application for the Instagram Firebase app. What do you think?
Vartis
6 years ago
Amazing course Brian ! Really hope that you're going to show us how to make video post!
jasonz1028
6 years ago
Hey Brian, thanks for the great video. I have a question regarding to Pagination, since you called observeSingleEvent with event type .Value, not childAdd every time when users upload a new image, it will not automatically append the new photo. What is another approach for this pagination with childAdd? I have been stuck in this problem for the last 3 days. Any help is going to be appreciated.
Stephan Dowless
6 years ago
I have also been stuck on this, any help would be much appreciated
wasim
6 years ago
I have also stuck on this issue, please any help to overcome this issue
smiller193
6 years ago
maybe use observe instead. That is constantly observing for new content
Didar Kamelinov
6 years ago
hey Brian, Firebase push ID`s are generated sin a way following creation time and date. So would it be correct to use thos values for pagination, i.e. use OrderByKey and sort according to firebase id`s. thanks
sconrad8
6 years ago
Hey Brian! These were some great tutorials. In the home feed, I just can't figure out how to expand a caption to show more text using a button. One way I tried, changes the size of every cell. I can't figure out how to pass the index from the cell in which the button was clicked back to the uiCollectionViewController to reload the data with the new size. Any help would be much appreciated. Thank you!
Brian Voong
6 years ago
sconrad8
6 years ago
You the man!
weare99
6 years ago
Brian one question why do you don't make in this hole project self.collectionView.reloadData not in the main thread Dispatch Queue main async. ? Is this not nessesary ?
Daniel Keinan
6 years ago
Hey Brain love the videos! I was wondering if you were going to add more tutorials at some point, and if so when. Is there a good way to set a default picture if the user doesn't select a photo instead of the plus sign? Or an edit profile section? If you don't want to add anything you obviously don't have to, the tutorials are already pretty amazing! Let me know when you see this. Thank you!
Daniel Keinan
6 years ago
Also maybe deleting users, posts, comments, etc...
Daniel Keinan
6 years ago
And maybe Private/Public Account where a user has to accept someone before someone can follow another person. (The accepting followers can be within the <3 icon). I want to create an app with multiple groups of people so you need codes/passwords to enter groups and I think the code for this would be similar. If you have any other suggestions for this please let me know!
Daniel Keinan
6 years ago
Notifications would also be super useful, when someone posts a photo or something
Daniel Keinan
6 years ago
Additionally maybe different types of logins, Signup with Facebook or twitter etc... Also how to verify an account, like send an Email to make verify that email before the account is actually made.
RayBee
6 years ago
Can someone tell me what episode provides code for the heart (like) button.
shender ramos
6 years ago
he does it on episode 38
RayBee
6 years ago
Also, is the app finished after episode 41?
RayBee
6 years ago
9-4-17 Hi Brian, I've finished all 41 episodes but I'm wondering if I've missed one or two episodes because I not able to find the lesson that covered updating posts, followers, following, or Edit Profile. Please advise. Thanks
planert41
6 years ago
Hi Brian. How would you update the pagination code to accommodate checking Firebase if the post has been liked? It looks like if you use the same code form HomeController, the pagination code gets called again (through collectionvew.reloaddata) after the first post is checked and added, but before the second post comes back, so the pagination gets called a second time and creates duplicate posts. I added a 0.25 second timer before having the collectionview.reload data, seems to work. But would like to know if there was a more concise way. Thanks
Arnaud Kapongo
5 years ago
Hi Brian, I have an error in my app : "Undefined symbols for architecture x86_64: "__T0So22AVCapturePhotoSettingsC12AVFoundation01_abC16SwiftNativeTypesACWP", referenced from: __T017InstagramFirebase16CameraControllerC18handleCapturePhotoyyF in CameraController.o "__T012AVFoundation39_AVCapturePhotoSettingsSwiftNativeTypesPAAE016availablePreviewc11PixelFormatG0Says6UInt32VGfg", referenced from: __T017InstagramFirebase16CameraControllerC18handleCapturePhotoyyF in CameraController.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) " what do i have to do
Brian Voong
5 years ago
Arnaud Kapongo
5 years ago
Thank you for the answer Brian.
Apurva Raj
5 years ago
Brian, I tried so much to make this work for main feed but it's really complex for me. When there are posts to fetch from more than one user I have no idea how to do it. Please suggest something.
Apurva Raj
5 years ago
Brian, I tried so much to make this work for main home feed but it's really complex for me. When there are posts to fetch from more than one user I have no idea how to do it. Please suggest something.
Stephan Dowless
5 years ago
send me an email at Dowless.stephan@gmail.com if you want to know how to paginate home feed
Stephan Dowless
5 years ago
If you would like to know how to paginate the home feed send me an email at dowless.stephan@gmail.com
nhershey7
5 years ago
Hey Brian! For all the various database calls throughout the Instagram Firebase tutorial, why did you decide to do them directly from Swift as opposed to building a REST API? What are the tradeoffs between the two? Do you have any videos on building a REST API to a Firebase relational database (or Firestore)?
Brian Voong
5 years ago
nhershey7
5 years ago
Makes sense - thanks!
Laurent Maquet
5 years ago
Hey Brian, I really don't understand why the following line should work : Database.database().reference().child("posts").child(uid).queryOrdered(byChild: creationDate) Indeed, creation date is not a child of any user uid ??? According to how we structure the database, the child that comes right after user id is the post id. It would be very helpful if you could explain it ! Thanks !!
Brian Voong
5 years ago
Tokyojogo
5 years ago
Hi Brian, Great work on the pagination, really appreciate it. I have a question though, in the pagination func, you did self.posts.forEach({ (post) in print(post.id) }) just before reloading the collection. You never really used this though. What is this suppose to handle? Thank you.
atalhassan
5 years ago
Hey Brian, how did you make a refresh spinner on the bottom to appear?
Brian Voong
5 years ago
stonypig1
5 years ago
I tried it and it works, but on the last chunk of paginated cell, the activity indicator stay there forever, won't go away, i must miss some logic check . any more advice?
David Wu
5 years ago
Hi Brian, I wonder if you could do a session to paginate the home feed. In other words, to paginate feeds across different users. It will be very helpful if you can do that -- I've been struggling for weeks without a working solution :((
Brian Voong
5 years ago
David Wu
5 years ago
Thanks for the response, Brian. I will be looking forward to the bonus lessons. But I'll start taking a look at cloud functions now to see if we will come up with something in common
Kirill Kudaev
5 years ago
Thank you! That would be very helpful, I'm also struggling with that at the moment :)
Maximilian Osborne
5 years ago
Great! I look forward to seeing these :)
Philippcalif
5 years ago
some new infos on this topic?
Ryann Stevenson
4 years ago
Hi Brian, Any news on when these bonus chapters will be available? Thanks Ryann
iHobbit
5 years ago
Brian, I noticed while working on this lesson that the app will crash if you drag to refresh several times in quick succession. I believe this occurs when the posts[] array gets emptied while cells are still being populated. I added a reload data call in the handleRefresh method to resolve this. Is there a cleaner way of avoiding this problem? @objc func handleRefresh() { posts.removeAll() collectionView?.reloadData() //prevents crash fetchAllPosts() }
qdnguyen110
5 years ago
I just got to this point and everything works fine except for the images load incorrectly and some repeating images in my, I don't know why? How's that please?
Kenny Ho
5 years ago
Hey qdnguyen110, I found the bug. I had the same problem too. Make sure that its " if self.posts.count > 0 && allObjects.count > 0 { " if you had " else if self.posts.count > 0 && allObjects.count > 0 { " that will cause the image duplication and re-posts of similar images. They are 2 separate "if" statements. Hopes this helps
qdnguyen110
5 years ago
I also got this message: 2018-02-13 21:34:18.463384-0800 InstagramFirebase[2045:234470] 4.8.1 - [Firebase/Database][I-RDB034028] Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ".indexOn": "creationDate" at /posts/pmJghDlp9lWbvhA2pWbTeFOKpdU2 to your security rules for better performance
smiller193
5 years ago
Hey Brian, I am having an error where on the second pass of the pagination call it loads the same ten pieces of data that it loaded the first time? Anyone else have this issue
jeffery
5 years ago
Hi Brian, i'm trying to make my firebase as flat as possible, so i store the real post data in a new node with postId as the key, and query postId in user_post node eg. " - postId: 1" (dummy 1). In this case, I need to query to get the postId first and then fire off anther ref.observeSingleEvent in side the query completion handler. Now, I got this weird situation when i append the post in the inner request closure, if some inner requests finish faster, it adds to the main thread queue earlier. Now the order of all the posts will get messed up. So i tried decrease the query limit number, I noticed that if the number is smaller than 6 everything works fine. so that is my current solution. I don't is there is any other good solution to this... the code: // i add var isPaging to prevent multiple call at the same time internal func paginatePosts() { print("\n start paging") isPaging = true let ref = Database.database().reference().child("user_posts").child(uid) var query = ref.queryOrderedByKey() let queryNum: UInt = 4 if posts.count > 0 { let value = posts.last?.postId query = query.queryEnding(atValue: value) } query.queryLimited(toLast: queryNum).observeSingleEvent(of: .value, with: { (snapshot) in self.refreshControl.endRefreshing() guard var allObjects = snapshot.children.allObjects as? [DataSnapshot] else { return } allObjects.reverse() if allObjects.count == 1 || allObjects.count == 0 { self.isPaging = false self.isFinishedPaging = true self.tableView.reloadData() } if self.posts.count > 0 && allObjects.count > 0 { allObjects.removeFirst() } allObjects.forEach({ (snapshot) in let postId = snapshot.key print(postId) Database.fetchPostWithPID(pid: postId, completion: { (post) in self.posts.append(post) print("inside: ", post.postId) if allObjects.last == snapshot { self.isPaging = false self.tableView.reloadData() } }) }) }) { (err) in print("Failed to paginate for posts:", err) } }
stonypig1
5 years ago
when we create a post, if I add a date string attach with post uid string : " 201803280921\(postuid)" then use queryorderbykey( ) , all posts will be ordered, then paginate, will this be a viable solution ? or use date as include inside the uid will have some kind of potential downside ? thanks
Brian Voong
5 years ago
stonypig1
5 years ago
thanks for your replay, it works, I apply paginationion on my main post page, thanks for this great extra add-on lesson, 10 days ago, I don't even know what pagination is. would you upload the code for how to make that indication progress bar, what I paginate at the end of my table ? thanks
stonypig1
5 years ago
does anyone run into a bug when do pagination on the main post, which when you paginate next load of data, the first post's user profile image is loading wrong, but first post's main image is correct, only the user profile image ? (and I already conditioly remove the first postuid)
stonypig1
5 years ago
would you tell me where is the code for refresher at the footer view after we paginate at the Project file ? please indicate the line and filename , sorry try to find it and can't see it. thanks
Tony Fitzgibbons
5 years ago
app crashes when refreshing, ant fix?
Tony Fitzgibbons
5 years ago
edit profile does not work.
sdowless
5 years ago
email me at dowless.stephan@gmail.com if you would like to see videos on how to do home feed pagination, hashtags/mentions, direct messaging, search feed with posts, and more.
ducward
5 years ago
Can someone explain how to get rid of the flickering that occurs when the images are loading during pagination?
Brian Voong
5 years ago
ducward
5 years ago
Thank you for the advice Brian! Also there's a weird bug in the photo selector controller I was hoping you can help with. Some of the images do not appear in the header view cell when selected from the collection view. It would flicker the image then shows an empty white background as opposed to the selected image.
esong2288
5 years ago
If we updated the pictures into FB using .childByAutoID could we use .queryOrderedByKey instead of querying by "timestamp"?
Brian Voong
5 years ago
esong2288
5 years ago
Oh ok I did some research and I think I see what you mean now. On a side note, do you know how to set a class for a layout constraint programatically?
drestaccz
4 years ago
thanks for the great video but I have a problem.I followed the steps correctly and the app works fine but , when I post a new picture the home feed gets updated with the image but not the userProfile Post image cell.I have to run the app again to update the userProfile post image. can you help
Shehryar Bajwa
4 years ago
hey Brian, each time i add a new image to the HomeController, and refresh the view pulling the view down, it gives me a Thread 1: Fatal error: Index out of range error. Would you happen to know why?
Stephan Dowless
4 years ago
email me at dowless.stephan@gmail.com for how to paginate home feed, implement hashtags/mentions and more
frankcrest
4 years ago
Whats the point of pagination if it still downloads all the data but 4 pictures at a time?
Brian Voong
4 years ago
Nick Stanislawski
4 years ago
I am very interested in seeing how pagination is preformed for the newsfeed. Is there a way you could make the source code available to show how this is preformed?
edison1
4 years ago
How can we fetch the likes? I've been trying and I get the value, but it doesn't seem to set the true or false..
edison1
4 years ago
var posts = [Post]() var isFinishedPaging = false fileprivate func paginatePosts() { print("Start fetching more for post") guard let uid = self.user?.uid else {return} let ref = Database.database().reference().child("posts").child(uid) var query = ref.queryOrdered(byChild: "CreatingDate") if posts.count > 0 { let value = posts.last?.creatingDate.timeIntervalSince1970 query = query.queryEnding(atValue: value) } query.queryLimited(toLast: 4).observeSingleEvent(of: .value, with: { (snapshot) in // print(snapshot.value) //we're paging for data differently so it has to be backward as oppossed to doing it with order a guard var allObjects = snapshot.children.allObjects as? [DataSnapshot] else {return} allObjects.reverse() if allObjects.count < 4 { self.isFinishedPaging = true } if self.posts.count > 0 && allObjects.count > 0 { allObjects.removeFirst() } guard let user = self.user else {return } allObjects.forEach({ (snapshot) in //converting the snapshot into the data and post objects guard let dictionary = snapshot.value as? [String: Any] else {return} var post = Post(user: user, dictionary: dictionary) post.id = snapshot.key //post.id = key self.posts.append(post) // guard let posttie = post.id else {return} // print(snapshot.key) //query with some type of limit is the key to pagination guard let posttie = post.id else {return} guard let currentuser = Auth.auth().currentUser?.uid else {return} Database.database().reference().child("likes").child(posttie).child(currentuser).observeSingleEvent(of: .value, with: { (snapshot) in print(snapshot) if let value = snapshot.value as? Int, value == 1 { self.post?.hasLiked = true } else { self.post?.hasLiked = false //self.posts.append(post) //self.collectionView.reloadData() } self.collectionView.reloadData() }) }) self.posts.forEach({ (post) in print(post.id ?? "") }) self.collectionView?.reloadData() }) { (err) in print("error", err) } }
Brian Voong
4 years ago
Brian Voong
4 years ago
edison1
4 years ago
the logic is just as you showed us. with this f let value = snapshot.value as? Int, value == 1 { self.post?.hasLiked = true } else { self.post?.hasLiked = false //self.posts.append(post) //self.collectionView.reloadData() } I also get the same snapshot value that my user liked the post with the 1
Brian Voong
4 years ago
Brian Voong
4 years ago
edison1
4 years ago
Trying to fetch the like, but only getting the value from snapshot and it does say 1, but I don't know how to fix it. The true value is set..
edison1
4 years ago
code below
Egya Eshun
4 years ago
Hey Brian, when I post a new picture, the home feed gets updated with the image but the userProfile Post Cells does not unless app is run again, please this is a crucial issue for me and maybe others so please try and reply ASAP. Thank you.
Brian Voong
4 years ago
edison1
4 years ago
Hey Brian can you take a look at my comment below. Have the code and everything. Please help :)
Cinquain
4 years ago
Wow what a painful process
iiKvs4
3 years ago
iiKvs4
3 years ago
Thank you a lot <3
GoldenRules
3 years ago
Hi Brian, The current Instragram version is pushing the list collectionviewcontroller to the cell you select from the grid. I am not sure if you have covered it in this course, but I couldn't check all the lessons so far. Is this explained? if yes in which lesson? and if not could you add it as a bonus lesson? Thank you
Clint Larenz Nurse
3 years ago
Hey Brain, Can you point us in the right direction on how to fetch multiple photos after you select a cell? For example if I am on the profile page and I select a photo, I can only fetch that one photo I selected. How can I fetch the next one up and so on below?
nawinest27
3 years ago
Hello Brian, If I want to make a swippable of that 3 tab (Like a real instagram app) from grid view -> list view -> bookmark or bookmark -> list view -> grid view, How to do that? ( Sorry for ask outside course's scope, but I buy your course for this section. I don't realize that you just toggle of the way to render cell.)
HELP & SUPPORT