Skip to content

Firestore onSnapshot work twice, when it should work only once. #2976

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

Closed
Vazgen7788 opened this issue Apr 23, 2020 · 1 comment
Closed

Firestore onSnapshot work twice, when it should work only once. #2976

Vazgen7788 opened this issue Apr 23, 2020 · 1 comment

Comments

@Vazgen7788
Copy link

Vazgen7788 commented Apr 23, 2020

  • Operating System version: MAC OSX
  • Browser version: Google Chrome Version 80.0.3987.163 (Official Build) (64-bit)
  • Firebase SDK version: 7.14.1
  • Firebase Product: Firestore

[REQUIRED] Describe the problem

Callback for realtime updates works wrong. If there is an open subscription for doc and I'm opening new subscription for collection with limit, callback of onSnapshot work twice. Instead it should work only once.

Steps to reproduce:

Create collection countries.

interface Country {
   name: string;
   createdAtUnix: number;
}

Seed some data.

Subscribe to the last doc ordered by createdAtUnix desc from countries collection.

      db.collection('countries')
      .doc(docId).onSnapshot((snap) => {

      })

Then subscribe to the collection ordered by createdAtUnix desc and set limit 1.

      db.collection('countries')
       .orderBy('createdAtUnix', 'desc')
       .limit(1)
       .onSnapshot((snapshot) => {
          // this work twice, first call's snapshot contains doc of subscription describe upper
          console.log('realtime collection snapshot');
       });

Relevant Code:

https://jsfiddle.net/vazgentigranich/9abz6suk/175/

Works ok
Click on yellow button (subscribe to collection), onSnapshot work once.
Click on red button (reset subscriptions).

Works wrong
Click on green button. (Subscribe to a single doc).
Click on yellow button (subscribe to collection) callback passed to onSnapshot work twice.

@schmidt-sebastian
Copy link
Contributor

@Vazgen7788 Thanks for filing this issue.

I believe the behavior you are seeing is as expected. When you are fetch countries/${docId} we store it in the local cache. We will then use the cached document for all new queries. In your case, countries/${docId} is the document that best matches the limit() query locally - at least at first. The backend then tells us that there is a different document that actually sorts higher and we raise another snapshot with the server's results.

To illustrate with an example:

  • You fetch db.collection('countries/a') with { createdAtUnix: 10 }. This is now in the cache.
  • You fetch db.collection('countries').orderBy('createdAtUnix', 'desc') .limit(1)
  • The SDK computes a list of results from cache. The only document that matches is countries/a.
  • The backend tells us about countries/b with {createdAtUnix: 20}. We store it in cache.
  • The SDK now recomputes the result for the limit query .countries/b is now the first ordered result and we raise another snapshot.

You can filter results from cache by looking at the fromCache metadata flag. This allows you to only react to change events that are synchronized with the backend.

@firebase firebase locked and limited conversation to collaborators May 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants