简体   繁体   中英

Why doesn't AngularFire return the latest data in my Firestore collection?

So I'm trying to build a real-time app to scrape data in the background (using Functions) and to display it on an Angular app. The Functions are working as expected and update my Firestore collection throughout the day. Getting the latest data to my frontend is the problem.

I started off by subscribing to valueChanges on a filtered collection. This works great to get the initial data, but it seems like changes aren't detected and the UI never updates with the new data.

getRunners(raceUid: string, date: Date): Observable<Runner[]> {
  return this.firestore
    .collection<Runner>(Collections.Runners, (ref) =>
      ref.where('raceUid', '==', raceUid)
        .where('created', '>=', date)
        .orderBy('created', 'asc')
        .orderBy('number', 'asc'),
    )
    .valueChanges();
}

After that I tried polling for the updated data by subscribing to the same valueChanges observable on a 10 second interval. But still the UI does not get updated with new data, even though my subscribe callback is definitely running.

I know the changes are there when I request it, because when I refresh the page all the changes display. So the initial call gets the latest data but it seems after that it just uses local cache maybe and never retrieves live data? Is that possible?

I'm using AngularFire 7.4.1 and I don't explicitly enable or disable persistence in my app.module .

EDIT: Here is my code that calls the getRunners method. This one is for polling:

this.updateInterval$
      .pipe(
        switchMap(() =>
          this.runnerService.getRunners(raceUid, new Date(this.today.getFullYear(), this.today.getMonth(), this.today.getDate(), 0, 0, 0)),
        ),
        takeUntil(this.raceChange$),
      )
      .subscribe((runners) => {
        this.runners = runners;
        this.lastUpdated = new Date();
      });

And here is what I started with initially:

this.runnerService
      .getRunners(raceUid, new Date(this.today.getFullYear(), this.today.getMonth(), this.today.getDate(), 0, 0, 0))
      .pipe(takeUntil(this.destroy$))
      .subscribe((runners) => {
        this.blockUi.stop();
        this.runners = runners;
        this.lastUpdated = new Date();
      });

Map the Runners snapshot changes to the require type using .pipe and map method like I have shown below:

In Service:

getRunners(raceUid: string, date: Date): Observable<Runner[]> {
  return this.firestore
    .collection<Runner>(Collections.Runners, (ref) =>
      ref.where('raceUid', '==', raceUid)
        .where('created', '>=', date)
        .orderBy('created', 'asc')
        .orderBy('number', 'asc'),
    )
    .snapshotChanges()
    .pipe(
      map((snapshots) => {
        return snapshots.map((snapshot) => {
          const data = snapshot.payload.doc.data();
          const id = snapshot.payload.doc.id;
          const updateTime = snapshot.payload.doc.updateTime;
          return { id, updateTime, ...data };
        });
      }),
    );
}

In Component we are getting the runners object with type safety involved then on subscribing you can implement your logic about runners.

this.runnerService
  .getRunners(raceUid, new Date(this.today.getFullYear(), this.today.getMonth(), this.today.getDate(), 0, 0, 0))
   .pipe(takeUntil(this.destroy$))
  .subscribe((runners) => {
        this.blockUi.stop();
        this.runners = runners;
        this.lastUpdated = new Date();
      });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM