-
Notifications
You must be signed in to change notification settings - Fork 879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
onSnapshot weird behaviour when using a different "orderby" .. #2094
Comments
@sr1dh4r I think there are two things going on here: First, you are not logging
Now we can start to see the second thing that's going on... You'll notice that the documents from the first 4 results (messages 3, 4, 5, 6) are the same results as from test1() but then you get 2 adds and 2 removes, which add the two missing docs (1 and 2) and removes the two extra docs (3 and 4) so that the results now represent the correct results for query2. The reason for this is that Firestore first gives you query results from running the query locally against any documents in cache, before it runs it against the backend. And because you have an existing listener on query1, docs 3, 4, 5, 6 were in cache and so they show up in that first set of query results. If we adjust your listen() function to include:
Then the new output is:
You'll notice that we get 2 snapshots. The first one is from cache and contains docs 5,6,3,4. The second one is not from cache and contains the correct docs: 5, 6, 1, 2. Depending on what you're trying to accomplish, this behavior may be 100% fine. As long as you respect the change.type, your UI should update accordingly. If you want to avoid seeing the cache results, you could have your code explicitly check for Another thing that would make a difference is if you enabled offline persistence. See https://firebase.google.com/docs/firestore/manage-data/enable-offline. With offline persistence, Firestore caches any document that you read or write, which means that it would cache the results from all 6 documents when you write them in app.prepare() and so they would all be in the cache, and so test2() would find the correct documents in cache right away. Hope this helps. I'm closing the issue, since I think this behavior is expected. But feel free to holler if anything's unclear. Thanks! |
@mikelehen Thanks a lot for looking into this. Didn't realize that there were two events when app.test1() was invoked. I think I understand the behaviour now. But I have some more concerns .. While its true that the effective results are correct, the ordering seems to be lost .. When I query with orderby 'likes' (app.test1()), I guess the documents are in the correct order in the first and second execution of the same query .. documents are sorted correctly with like-count 5,4,3,2 When I query with order by comments (app.test2()), I get the documents with comment count [3,2,1,0] and [1,0,5,4], so effectively 3,2,5,4 while the re-execution of the query gives me 5,4,3,2 as shown below. While the query is returning the correct set, the ordering is lost and this becomes a problem when presenting the data to the user. It also creates problems identifying new content that needs to be shown above the existing content. I guess I can manage this when presenting the data but wanted to see if there is something that can be done in the query phase itself. I did try to ignore snapshot.metadata.fromCache=true case but turns out I get empty results when I do that for the first execution and get the correct ordered set on the second execution of a query. So I guess that's not a solution ? Also, offline persistance probably won't help in case the data is written by another user to the same collection so not sure if I can rely on that. app.test3() app.test3() fyi, I removed the changes.reverse() in the listen function to avoid any confusion (in the test script shared earlier) |
@sr1dh4r To recover the ordering, you'll need to use The other option which is much simpler but possibly a little less efficient is to just use |
I'm getting different results for the same query, after running a query with a different orderby field on same collection.
Follwing is the output of a test functions I'm running from js console .. app.test2() behaviour is different during each invocation (the second invocation is the correct result). Originally (on a different collection), the issue was that test3 was showing incorrect results and on second invocation, shows the correct result.
>app.test1()
undefined
hmm.html:81 {comments: 3, likes: 1, msg: "message3", timestamp: io}
hmm.html:81 {comments: 2, likes: 0, msg: "message4", timestamp: io}
hmm.html:81 {comments: 1, likes: 5, msg: "message5", timestamp: io}
hmm.html:81 {comments: 0, likes: 4, msg: "message6", timestamp: io}
>app.test2()
undefined
hmm.html:87 {comments: 2, likes: 0, msg: "message4", timestamp: io}
hmm.html:87 {comments: 3, likes: 1, msg: "message3", timestamp: io}
hmm.html:87 {comments: 0, likes: 4, msg: "message6", timestamp: io}
hmm.html:87 {comments: 1, likes: 5, msg: "message5", timestamp: io}
hmm.html:87 {comments: 4, likes: 2, msg: "message2", timestamp: io}
hmm.html:87 {comments: 5, likes: 3, msg: "message1", timestamp: io}
hmm.html:87 {comments: 2, likes: 0, msg: "message4", timestamp: io}
hmm.html:87 {comments: 3, likes: 1, msg: "message3", timestamp: io}
>app.test2()
undefined
hmm.html:87 {comments: 4, likes: 2, msg: "message2", timestamp: io}
hmm.html:87 {comments: 5, likes: 3, msg: "message1", timestamp: io}
hmm.html:87 {comments: 0, likes: 4, msg: "message6", timestamp: io}
hmm.html:87 {comments: 1, likes: 5, msg: "message5", timestamp: io}
Steps to reproduce:
I have prepared a test html file with the script and dependencies @ https://www.dropbox.com/s/pt3f5pmugivtpxw/hmm.html?dl=0
In the js console, you need to run app.prepare() to create a "testing" collection.
executing app.test1() will get the list with orderby timestamp
executing app.test2() will get the list with orderby likes
executing app.test3() will get the list with orderby comments
The weird part is, if I run app.test(), which will run all the three functions above in a single shot, the results are as expected. It's only if I invoke them manually from the shell (basically some delay between each call) I see the issue.
The text was updated successfully, but these errors were encountered: