Actualizar los campos del mapa en todos los documentos del firestore

Estoy trabajando en una aplicación web en angular 6 y la Biblioteca angularfire2. Tengo dos series,

Preguntas frecuentes

y teams. Si cambia el nombre del equipo, debe cambiar el nombre del equipo en la documentación del usuario.
export interface User {
  firstName: string;
  emailAddress: string;
  team: TeamId;
}

export interface UserId extends User {
  id: string;
}

export interface Team {
  name: string;
  abbreviation?: string;
}

export interface TeamId extends Team {
  id: string;
}
Curso:
const team: Team = {
  name: 'Yankees',
  abbreviation: 'YKS'
};

this.teamService.updateTeam('kbdf673bksbdj', team)
  .then(async res => {
    // The name has changed
    if ('Yankees' !== team.name) {
      await this.teamService.updateTeamNameInOthers('kbdf673bksbdj', team.name);
    }
  }, err => {
  });
Del servicio:
private teamsCollection: AngularFirestoreCollection<Team>;
teams: Observable<TeamId[]>;

constructor(
  private afs: AngularFirestore) {
  this.teamsCollection = afs.collection<Team>('teams');

  this.teams = this.teamsCollection.snapshotChanges().pipe(
    map(actions => actions.map(a => {
      const data = a.payload.doc.data() as Team;
      const id = a.payload.doc.id;
      return {id, ...data};
    }))
  );
}

updateTeamNameInOthers(id: string, newName: string) {
  this.userService.getUsers().subscribe(users => {
    users.forEach(user => {
      if (user.team.id === id) {
        this.afs.collection('users').doc(user.id)
          .set({team: {name: newName}}, {merge: true});

        // I have tried
        // .update({team: {name: newName}});
      }
    });
  });
}
Lo intenté.
updateTeamNameInOthers(id: string, newName: string) {
    this.userService.getUsers().subscribe(users => {
      users.forEach(user => {
        if (user.team.id === id) {
          const userRef = this.afs.collection(config.collection_users).doc(user.id).ref;

          this.afs.firestore.runTransaction(transaction => {
            transaction.get(userRef).then(userDoc => {
              transaction.update(userRef, {team: {name: newname}}, {merge: true});
            });
          });
        }
      });
    });
  }
Puede actualizar inmediatamente cualquier propiedad del equipo, pero si desea cambiar todas las propiedades del equipo al mismo tiempo, la documentación del usuario no se actualizará. No estoy seguro de que sea la mejor manera.
Mi objetivo es cambiar el nombre del equipo en todos los documentos de usuario que pertenecen al equipo si el nombre del equipo cambia. Hay muchas maneras de hacerlo. No recomiendo hacer estos cambios desde el frente.
Si la estructura de la base de datos es:
teams/team

users/user {
  team: { (not as a subcollection)
    id: string;
  }
}
Entonces tienes que consultar a todos los usuarios como lo haces ahora. La diferencia es que desea realizar la operación con transaction o no en absoluto si se produce un error. Luego usará esta transacción para realizar operaciones DB similares a las interceptadas de las respuestas de enlace users y

La mejor manera de manejarlo para mí

, donde X es su método DB.
Alternativamente, recomiendo usar Cloud Functions para realizar esta función. Con él, puede escuchar los cambios en los registros sin depender del cliente para hacer los cambios. Si el usuario hace cambios válidos, la funcionalidad Cloud puede hacer cambios transaccionales en lugar de realizar cambios de forma poco fiable en el lado del cliente.
Después de editar 1
Debe mover la línea db.firestore.runTransaction(transaction => por encima de transaction.X para que todas las operaciones puedan compartir la misma transacción. De esta manera, ninguna de las actualizaciones se actualizará si se produce un error.
Después de charlar
La solución final es usar async/await en firestore. Ejecute la transacción, devuelva el compromiso y actualice el registro usando la transacción. Actualización, después de la resolución del compromiso. ¡La segunda parte de la solución es asegurarse de que no se suscribe a la colección que desea actualizar en la actualización!
// service method
getData(value: string): Promise<FancyType[]> {
  return this.afs.collection<FancyType>(
    'collection',
    ref => ref.where('value', '==', value)
  ).snapshotChanges()
  .pipe(
    take(1),
  ).toPromise();
}

// update method 1 transaction
const data: FancyType[] = await this.service.getData();

if (data) {
  await this.afs.firestore.runTransaction(t => {
    return new Promise((res, rej) => {
      data.forEach(d => {
        const dataRef = this.afs.collection('collection').doc(d.id).ref;
        transaction.update(dataRef, {...d, hello: 'World'});
      });
      res();
    });
  });
}

// alternate update method 2 batch
const data: FancyType[] = await this.service.getData();
const batch = this.afs.firestore.batch();

if (data) {
  data.forEach(d => {
    const dataRef = this.afs.collection('collection').doc(d.id).ref;
    batch.update(dataRef, {...d, hello: 'World'});
  });

  batch.commit()
    .then(res => {
      //on success
    }).catch(err => {
      //on error
    });
}
Here is a reference para transacciones y lotes.