Search code examples
javascriptgoogle-cloud-firestoreangularfire2

Angular Firestore - search for and update single document


I'm new to web (and everything asynchronous). I'm trying to complete a two step process in an Angular + Firebase app:

  1. Query a Firestore collection to find the ID of a document that matches a filter (name == 'theName').
  2. Use the ID to then update the document.

I'm coming from the embedded world where I can do something like this (context of the app - I'm trying to keep track of results in a combat robotics competition).

// Update the winning robot's doc with results

// Find the ID of the robot we're looking for (ex. winningRobotName = "Some Name")
this.firestore.collection('robots', ref => ref.where('name', '==', winningRobotName)).snapshotChanges()
  .subscribe(data => {
    this.bots = data.map(e => {
      return {
        id: e.payload.doc.id,
        name: e.payload.doc.data()['name'],
        // other fields
      } as Robot;
   })
});

let robot = this.bots[0];  <--------- This doesn't work because I reach here before the above call returns.

// Update this robot with new fields
this.firestore.doc('robots/' + robot.id)
  .update({
    fightCount : robot.fightCount + 1,
    winCount : robot.winCount + 1,
    // other updates
  });

How does one wait for one subscription to return before executing another command? Do you nest the subscriptions? Is there something really basic I just don't know about yet?

Thanks.


Solution

  • I don't think AngularFire helps you here, and would instead do this directly on the regular JavaScript SDK:

    ref.where('name', '==', winningRobotName))
       .get()
       .then((snapshots) => {
         snapshots.forEach((doc) => 
           doc.ref.update({
             id: doc.id,
             name: doc.data().name
           })
       })
    })
    

    I'm not exactly sure what name: doc.data().name is supposed to do (as it's an identity operation, delivering the same result as its input), but left it in just in case this matters to you.