How can I query Firestore DB only once? I want to avoid that when something changes on a document the snapshotChanges() emit new value

I am not so into Firestore and I am findong a big problem working on an Angular application.

Into a service class I defined this method that retrive objects into a specific bids collection of my Firestore DB:

  findArtistBidsAppliedByCurrentWall(bid):Observable<Bid[]> {
    console.log("findArtistBidsAppliedByCurrentWall() START")
    return this.db.collection('bids',
        ref=> ref.where("wallId", "==", bid.wallId))
        .snapshotChanges()
        .pipe(
            map(snaps => {
                const bids = this.convertSnaps<Bid>(snaps);

                return bids;
            })
        )
  }

As you can see this method uses the snapshotChanges() method to retrieve data from my collection.

The problem is that using snapshotChanges() method a change made to a property into a document of the bids collection is automatically detected and the related Observable emit new values.

I have to avoid this behavior because I am using this findArtistBidsAppliedByCurrentWall() into another method that retrieve the list of object calling the previous method and then update all these objects on Firestore changing some fields values. So it happens that the other method have the following problem:

  • Call findArtistBidsAppliedByCurrentWall() in order to retrieve the list of object to be updated.
  • Update these objects.
  • When an object is updated the Observable returned by findArtistBidsAppliedByCurrentWall() emit new values beucase it is using snapshotChanges()
  • The logic of my update system is broken

So what could be a good way to handle this situation? How can I avoid this behavior? My idea is that in this case the findArtistBidsAppliedByCurrentWall() have to simply emit an array of Bids instead emitting an Observable but I am not sure that this is a good solution.

For completeness this is the code of the method that call the previous findArtistBidsAppliedByCurrentWall():

  acceptOrRejectArtistBid(bid:Bid, action: string) {
    console.log("acceptArtistBid() start !!!");

    let bidId = bid.bidId;

    let listOfBids: Array<any>;

    return this.findArtistBidsAppliedByCurrentWall(bid).pipe(
      // here you use the map of Observable to transform the list, and within this map you call the map Array method to run the transformation on each bid
      map(artistsBisdList => {
                              return listOfBids = artistsBisdList.map(currentBid => {

          
                                                  let currentBidDoc = this.db.collection("bids").doc(bid.bidId);

                                                  console.log("CURRENT BID DOC: ", currentBidDoc);

                                                

                                                  return currentBid;
                                                })

                             }
      ),

      map(bidList => {
                        console.log("TEST " , bidList);

                        bidList.forEach(currentBid => {
                          // HERE MY FIRESTORE UPDATE LOGIC FOR EACH OBJECT IN THE ARRAY                        
                        }); 
                      })
    )
        
  }

As you can see in the second method i first retrieve the list of Bids object using the previous findArtistBidsAppliedByCurrentWall() method that return an Observable, then I put into a pipe chain a first map operator to iterate on the retrieved element into emitted by the Observable, following I put another map where I iterate on the collection in order to perform the updates on the DB.

How can I correctly avoid that when an update is made on an FireStore collection document the snapshotChanges() emit new values?

Source: Angular Questions