yashatreya
yashatreya

Reputation: 842

Firebase firestore Pagination is returning duplicate results

I'm creating a social feed where I want to have infinite scrolling, using firebase pagination but the query is returning the same each time even when I have a lot of different data in my firestore database.

This is my initial query:

const getThreads = async () => {
    try {
      setLoading(true);
      const ref = firestore()
        .collection('Discover')
        .orderBy('rank', 'desc')
        .limit(10);

      let docSnaps = await ref.get();

      if (docSnaps.empty !== true) {
        let docData = docSnaps.docs.map(document => {
          return {
            data: document.data(),
            id: document.id,
          };
        });
        setLastVisible(docData[docData.length - 1].id);
        setThreads(docData); //Setting the data to display in UI
      }
      setLoading(false);
    } catch (e) {
      setLoading(false);
      console.log(e);
      Alert.alert(
        'Oops! Looks like something went wrong',
        'Please try again later',
        [{text: 'OK'}],
      );
    }
  };

As you can see each post/thread is being ordered by a rank field. And I'm setting the last visible as the documentId which is being used in the below query to get more posts/threads

async function getMoreThreads() {
    try {
      console.log('Getting More threads');
      if (lastVisible !== null) {
        setRefreshing(true);
        const ref = firestore()
          .collection('Discover')
          .orderBy('rank', 'desc')
          .startAfter(lastVisible)
          .limit(10);

        let docSnaps = await ref.get();

        if (docSnaps.empty !== true) {
          let docData = docSnaps.docs.map(document => {
            return {
              data: document.data(),
              id: document.id,
            };
          });
          console.log('DocData', docData.length);
          setLastVisible(docData[docData.length - 1].id);
          setThreads([...threads, ...docData]);
        }
        setRefreshing(false);
      }
    } catch (e) {
      console.log('Error getting more', e);
      Alert.alert(
        'Oops! Looks like somthing went wrong',
        'Please try again later',
        [{text: 'OK'}],
      );
    }
  }

My hypothesis of why this is happening is because I'm using documentIds to paginate and my document Ids are numeric long integer strings like this 1002103360646823936,1259597720752291841, 974895869194571776, etc.

Help would be very much appreciated.

Upvotes: 4

Views: 1613

Answers (1)

Christilyn Arjona
Christilyn Arjona

Reputation: 2283

Your hypothesis is correct. The field that you are using to paginate with startAfter(...) should match the field you are using in the orderBy(...) method - in this case, your startAfter(...) method is assuming that you are passing it a rank value.

You can pass in the DocumentSnapshot object in your startAfter(...) method instead:

const ref = firestore()
          .collection('Discover')
          .orderBy('rank', 'desc')
          .startAfter(documentSnapshot) // document snapshot of the last element
          .limit(10);

Upvotes: 8

Related Questions