3

I have a database that holds Posts. At a future point, my database may hold a very large number of Posts. I am confused as to what to do, as I cannot decide between the few options that I've thought of so far:

1) Load all Posts at once and store them into an Posts[] array, and just show all posts on the TableView that displays them.

2) Load 10 Posts at once and display those 10 at a time, then implement a function that allows the user to scroll and to load 10 more at a time. These 10 values that are loaded will then be added to the TableView.

Now, option #1 seems simple and attractive, as it is what I currently have set up. However, I am not sure if it would be problematic or not to constantly load hundreds of posts every time a user opens the page that displays Posts.

Option #2 seems complex, as I have no idea how to only load 10 Posts at once using Firebase. I am using a .childAdded observation to gather the data, and that usually loads all of the Posts. An alternative idea I had that may or may not be useless is loading all Posts into the Posts[] array but only displaying 10 at a time. This option is attractive because users won't have to load every single post every time they view the TableView that contains the posts. I am also hesitant to take this option because I would have to alter my data structure quite a lot. The current set up is:

root/posts/post-id/post-info

In which the post-info node holds information relevant to the post, and does not contain an index, which I have a feeling that option #2 would require.

I'm quite stuck here. What's the best action to take in a situation like this?

Subject X
  • 43
  • 4
  • If your list is going to increase, you'll definitely want to paginate it. Past a certain point, it may get too large to even fetch in one request and will start simply timing out. I haven't used Firebase so I can't give a concrete answer on how exactly to do this with it but just googling shows that there are a few mechanisms in place to let you do so, in particular using the `endAt` and `limitToLast` chaining methods on your requests. I found a pretty informative post [here](https://medium.com/@wcandillon/firebase-live-pagination-474748853e52) – Dima Jul 22 '17 at 23:24
  • Related question on how to [load X items from Firebase](https://stackoverflow.com/questions/37430881/swift-ios-firebase-paging) – nathan Jul 23 '17 at 16:34

1 Answers1

1

I was having the same problem creating a "forum" like app. There were a lot of threads and loading them all at once was not the right approach.

If I were you I would stick to method 2: Load X number of posts, when TableView is scrolled to the bottom (or almost to the bottom) load additional posts and display them.

Here is a quick example: You need a variable which will hold information on how much posts should be displayed:

var numberOfPosts: Int = 20

Query your posts using queryLimited:

reference.child("child").child("child").queryLimited(toLast: UInt(numberOfPosts))

This will return last X posts. You should also order it by some key to make sure you really have latest posts in the right order:

reference.child("child").child("child").queryOrdered(byChild:"timestamp").queryLimited(toLast: UInt(numberOfPosts))

So the idea is, first time it will load 20 posts. The next time it should load 40, etc. That is why we need to implement something to recognise that all the posts were displayed and we need to load new ones. I am doing that with scrollView function - each time I am almost reaching the bottom, additional posts load. Implement scrollView didScroll:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if (scrollView.contentOffset.y + 100) >= (scrollView.contentSize.height - scrollView.frame.size.height) {
      // You have reeached bottom (well not really, but you have reached 100px less)
      // Increase post limit and read posts
      numberOfPosts += 20
      readPosts()
    }
  }

If you have UITableViewDelegate in the same class, function should be working by itself since TableView uses scrollView delegate.

So this should be enough to get you going. I don't have the actual code right here so can't really paste it to help you.

By the way, I am using .value and not .childAdded but you should be able to implement something like this anyway.

ZassX
  • 1,369
  • 2
  • 14
  • 35
  • Thank you! Just couldn't find the .queryOrdered & .queryLimited functions before. – Subject X Jul 29 '17 at 02:20
  • @ZassX I like this approach but wouldn't each new load be increasingly slower because numberOfPosts is getting bigger? If there were 1000 posts, then in order to get to post 1000, you'd have to basically load the entire 1000 right? – Jack Chen May 12 '21 at 18:28