Firestore startAfter() returning the same data in infinite scrolling when ordered by descending timestamp

断了今生、忘了曾经 提交于 2020-08-26 09:08:54

问题


I'm writing a profile page with chronological user posts (latest post on top) using Firestore on Ionic by setting orderBy() to "timestamp" descending. I'm using Ionic's infinite loading to load more posts when the user reaches the bottom, but the result is that Firestore loads the exact same posts over and over again. Please help!

Hi!

Sorry if this is a beginner question, but I've been wrapping my head around this for sever hours to no avail. The pagination works properly when in ascending order, but loads the same posts when in descending order. I've looked at trying the following alternatives, but they would not be cost-efficient:

  1. Change the limit when user reaches the bottom: this would lead to reading all the posts again and again
  2. Do it in ascending order but reverse the array: would defeat the purpose of pagination
  3. use a query (where) to grab the documents before x timestamp: works in theory, but is a bit hacky and I would really want to know how startAfter() works since it's already there.

.

'''

READ_posts__profile(uid,limit, start) : Promise<[]>
  {
      return new Promise((resolve, reject) =>
      {

         if (start == null)
         {
            resolve();
         }
        else if(start == 'head')
        {
            start = new Date();
        }
            console.log(start);


         this._DB.collection(this.ref.posts + uid + '/userposts' )
         .orderBy("timestamp", 'desc').startAfter(start).limit(limit)
         .get()
         .then((querySnapshot) =>
         {

            let obj : any = [];

            console.log(obj);

            querySnapshot
            .forEach((doc : any) =>
            {
               obj.push({
                  id             : doc.id,
                  content        : doc.data().content,
                  likes          : doc.data().likes,
                  timestamp      : doc.data().timestamp,
                  comments       : doc.data().comments
               });

            });

            resolve(obj);
         })
         .catch((error : any) =>
         {
            reject(error);
         });
      });
  }

'''

Expected result: Infinite scrolling of posts from latest to oldest Result: Infinite scrolling of first x posts again and again (limit is x)

Thank you for taking the time to read. Hope to hear from you guys soon!

UPDATE FOR FUTURE REFERENCE: Rather than using the doc itself in .startAfter(), it worked with using doc.timestamp like so:

      this._DB.collection(this.ref.posts + uid + '/userposts' )
  .orderBy("timestamp", "desc").startAfter(start.timestamp).limit(this.limit)
  .get()
  .then(querySnapshot =>
  {

回答1:


The problem is that startAfter() is expecting a query cursor for the parameter, not the timestamp that you are passing.

A query cursor identifies the document:

  • Paginate data with query cursors | Firebase

What you need to do is save the doc to a variable at the class level and then pass that in with the next one:

// in the class variables at the top
latestEntry: any;

// then save a reference to it
this.latestEntry = data[data.length - 1].doc;

// Now you can use the latestEntry to query with startAfter
.startAfter(this.latestEntry)

This is the general theory. When I got this working myself in an app I used the code in this answer.

It's going to need quite a lot of rewriting of your code to do this, which is beyond the scope of the time I have right now, but hopefully this will help you resolve it yourself.




回答2:


In my case I added the query like this

query.startAfter(lastId)

where it should have been

query = query.startAfter(lastId)


来源:https://stackoverflow.com/questions/57375231/firestore-startafter-returning-the-same-data-in-infinite-scrolling-when-ordere

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!