Есть много способов сделать это.Я не рекомендую вносить эти изменения из внешнего интерфейса.
Если ваша структура базы данных:
teams/team
users/user {
team: { (not as a subcollection)
id: string;
}
}
Тогда вам придется опрашивать всех пользователей, таких как вы.Разница в том, что вы захотите использовать транзакцию для выполнения всех операций вместе или вообще не выполнять их при возникновении ошибки.Затем вы будете использовать транзакцию для выполнения операций с БД, как показано в связанном ответе db.firestore.runTransaction(transaction =>
и transaction.X
, где X - ваш метод БД.
В качестве альтернативы , я рекомендую сделатьэтот вид функциональности с облачными функциями .Благодаря этому вы можете прослушивать изменения в записи, не полагаясь на клиентскую сторону для внесения изменений.Если пользователь вносит корректное изменение, облачные функции могут выполнять транзакционные изменения вместо ненадежного выполнения изменений на стороне клиента.
После редактирования 1 Вы должны переместить строку this.afs.firestore.runTransaction(transaction => {
выше users.forEach(user => {
, поэтому все операции могут использовать одну и ту же транзакцию.Таким образом, если с одним из обновлений произошла ошибка, ни одно из них не будет обновлено.
После чата Окончательное решение состояло в том, чтобы использовать async / await с firestore.runTransaction, вернуть обещаниеобновите записи с помощьюaction.update, разрешив обещание после.Вторая часть решения заключалась в том, чтобы гарантировать, что вы не подписаны на коллекцию, которую вы обновляете в рамках обновления!
// 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
});
}
Вот справочник для транзакций и пакетов.