我在Firestore上有如下所示的删除操作。它工作正常。但是你能告诉我如何使用transaction
来做这件事吗?此时如果有任何失败,它会进行部分删除。
async delete(project: DtoProject): Promise<void> {
await this.fireStore.doc<Project>(`projects/${project.id}/`).delete();
const budgetGroupsQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/budgetGroups`).get();//budgetGroups
budgetGroupsQuerySnapshot.forEach(async (doc: any) => {
await this.fireStore.doc<BudgetGroup>(`projects/${project.id}/budgetGroups/${doc.id}`).delete();
});
const budgetsQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/budgets`).get();//budgets
budgetsQuerySnapshot.forEach(async (doc: any) => {
await this.fireStore.doc<Budget>(`projects/${project.id}/budgets/${doc.id}`).delete();
});
const categoriesQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/categories`).get();//categories
categoriesQuerySnapshot.forEach(async (doc: any) => {
await this.fireStore.doc<Category>(`projects/${project.id}/categories/${doc.id}`).delete();
});
const transactionsQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/transactions`).get();//transactions
transactionsQuerySnapshot.forEach(async (doc: any) => {
const notesQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/transactions/${doc.id}/notes`).get();//notes
notesQuerySnapshot.forEach(async (n: any) => {
await this.fireStore.doc<Note>(`projects/${project.id}/transactions/${doc.id}/notes/${n.id}`).delete();
});
const photosQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/transactions/${doc.id}/photos`).get();//photos
photosQuerySnapshot.forEach(async (p: any) => {
await this.fireStore.doc<Photo>(`projects/${project.id}/transactions/${doc.id}/photos/${p.id}`).delete();
});
await this.fireStore.doc<Transaction>(`projects/${project.id}/transactions/${doc.id}`).delete();
});
}
答案 0 :(得分:1)
您必须获取要删除的所有文档引用,然后在事务中使用 Promise.all 遍历每个引用。
如下所示:
deleteAll(arrayOfDocReferencesToBeDeleted){
return this.db.runTransaction(async transaction => {
return Promise.all(arrayOfDocReferencesToBeDeleted.map(async (ref) => {
await transaction.delete(ref);
}));
}).then(() => console.log('success')).catch(() => console.log('error'))
}
在您的情况下,您可以将您的功能更改为此代码:
async delete(project: DtoProject): Promise<void> {
//first get all the doc referencs that you want to delete
var firstReferenceToBeDelete = this.fireStore.doc<Project>(`projects/${project.id}/`);
//get all the docs from the collection
const budgetGroupsQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/budgetGroups`).get();//budgetGroups
//map the doc references to an array
var groupsRef = budgetGroupsQuerySnapshot.docs.map((doc) => { return this.fireStore.doc<BudgetGroup>(`projects/${project.id}/budgetGroups/${doc.id}`) });
//repeat it until you have all the doc references that you want to delete
const budgetsQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/budgets`).get();//budgets
var budgetsRef = budgetsQuerySnapshot.docs.map((doc) => { return this.fireStore.doc<Budget>(`projects/${project.id}/budgets/${doc.id}`) });
const categoriesQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/categories`).get();//categories
var categoriesRef = categoriesQuerySnapshot.docs.map((doc) => { return this.fireStore.doc<Category>(`projects/${project.id}/categories/${doc.id}`) });
const transactionsQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/transactions`).get();//transactions
var notesRef = [];
var photosRef = [];
var lastRefs = [];
transactionsQuerySnapshot.forEach(async (doc: any) => {
const notesQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/transactions/${doc.id}/notes`).get();//notes
var notes = notesQuerySnapshot.docs.map((note) => {
return this.fireStore.doc<Note>(`projects/${project.id}/transactions/${doc.id}/notes/${note.id}`)
});
notesRef.concat(notes);
const photosQuerySnapshot = await this.authenticationProvider.firestoreDb.collection(`projects/${project.id}/transactions/${doc.id}/photos`).get();//photos
var photos = photosQuerySnapshot.docs.map((photo) => { return this.fireStore.doc<Photo>(`projects/${project.id}/transactions/${doc.id}/photos/${photo.id}`) });
photosRef.concat(photos);
lastRefs.push(this.fireStore.doc<Transaction>(`projects/${project.id}/transactions/${doc.id}`));
});
//make a single array with them
var arrayOfDocReferencesToBeDeleted = [firstReferenceToBeDelete].concat(groupsRef, budgetsRef, categoriesRef, notesRef, photosRef, lastRefs)
//after you have an array with all your doc references you can iterate them in the transaction
return this.db.runTransaction(async transaction => {
return Promise.all(arrayOfDocReferencesToBeDeleted.map(async (ref) => {
await transaction.delete(ref);
}));
}).then(() => console.log('success')).catch(() => console.log('error'))
}
当然你应该在另一个函数中破坏这个功能,但这样可行。