Firebase orderByChild with startAt()'s second

2019-01-09 18:26发布

问题:

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.

回答1:

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.