问题
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:
- Change the limit when user reaches the bottom: this would lead to reading all the posts again and again
- Do it in ascending order but reverse the array: would defeat the purpose of pagination
- 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