3

I have a Firebase invocation which looks like this,

      ref.child(`floorPosts/${this.props.floorName}`)
        .orderByChild('numberOfLikes')
        .limitToLast(15)
        .once('value', (snapshot) => {
          var topPosts = [];
          snapshot.forEach((childSnapshot) => {
            var post = childSnapshot.val();
            post.key = childSnapshot.key();
            topPosts.unshift(post);
          });
          this.lastPostKeyTop = topPosts[topPosts.length - 1].key;
          this.setState({
            topPosts,
            isLoading: false
          });
      });

Now what I'm trying to do, is when the user scrolls to the bottom of the page, I invoke this function.

ref.child(`floorPosts/${this.props.floorName}`)
    .orderByChild('numberOfLikes')
    .startAt(null, this.lastPostKeyTop)
    .limitToLast(15)
    .once('value', (snapshot) => {
      var topPosts = [];
      snapshot.forEach((childSnapshot) => {
        var post = childSnapshot.val();
        post.key = childSnapshot.key();
        topPosts.unshift(post);
      });
      this.setState({
        topPosts: this.state.topPosts.concat(topPosts),
        isLoading: false,
      });
  });

However, it's concatenating the same first 15 results as it initially did. .startAt takes in a a second argument, which (I believe) is the key of the last item which was fetched from firebase the initial fetching. However, this doesn't seem to be working in my case. I have a hunch it's something to do with the snapshot.forEach code.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Tyler McGinnis
  • 34,836
  • 16
  • 72
  • 77

1 Answers1

5

sorry for the incredibly late answer Tyler

The second argument to startAt() is only used to disambiguate between items that match the first argument. So you must pass in both the value of numberOfLikes to start at and the key of the last item on the first page (often referred to as the anchor item).

Also note that this means the first item of the next set of results will be the same as the last item in the previous set of results. So you'll need to retrieve one extra item.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Hahaha. Amazing. <3 you puf! – Tyler McGinnis Jul 03 '17 at 23:41
  • I was searching for answer about this parameter to link to and then found your question. It's been only slightly less than two years. :-) – Frank van Puffelen Jul 03 '17 at 23:45
  • Follow up question: What happens if someone clicked "like" since we did the first query ? This would mean the first argument `numberOfLikes` does not match what is in the db anymore. Would `startAt()` still work correctly ? – Reyn Mar 25 '18 at 19:42