0
votes

I'm using Cloud Firestore and when I add a document to one of my root collections and I log the result of snapshotChanges() on that collection, the log shows every doc in that collection.

I understand that Firebase charges based on documents returned such as in a query.

Does snapshotChanges() also cause a billable read on each doc?

firebase.service.ts

@Injectable()
export class FirebaseService {

  public recordsCollection: AngularFirestoreCollection<any[]>;
  public records$: Observable<any[]>;

  public financialsCollection: AngularFirestoreCollection<any[]>;
  public financials$: Observable<any[]>;

  constructor(private db: AngularFirestore) {

    this.recordsCollection = this.db.collection<any[]>('records');
    this.records$ = this.mapAndReplayCollection(this.recordsCollection);

    this.financialsCollection = this.db.collection<any[]>('financials');
    this.financials$ = this.mapAndReplayCollection(this.financialsCollection);

  }

  private mapAndReplayCollection(collection: AngularFirestoreCollection<any[]>): any { 
   return collection.snapshotChanges()
      .pipe(
        map(changes => {
          return changes.map(a => {
           console.log(`${collection.ref.id} snapshotChanges: ${a.payload.doc.id}`);
           return { realId: a.payload.doc.id, ...a.payload.doc.data() }
          })
        }),
       shareReplay(1),
    );
  }

}
1
shareReplay will save the first emission and always emit the last result just like behavior subject. - Fan Cheung
Thank you @FanCheung. Revised question to focus solely on snapshotChanges() in regards to billable reads. - user1052888

1 Answers

0
votes

Think your approach is correct, the emissions are all coming form your presistent collection instance (hot observable). but I will suggest just extending the financials Collection chain to create financial$ and financialsWithReplay$ stream to look more explicit instead of wrapping them in the function (and probably that's why you not sure if its cached the last result)

this.financials$ = this.financialsCollection.snapshotChanges()
  .pipe(
    map(changes => {
      return changes.map(a => {
       console.log(`${collection.ref.id} snapshotChanges: ${a.payload.doc.id}`);
       return { realId: a.payload.doc.id, ...a.payload.doc.data() }
      })
    })
);

this.financialsWithReplay$=this.financials$.pipe(shareReplay(1))