【问题标题】:Build Firestore transaction operation构建 Firestore 事务操作
【发布时间】:2018-07-13 08:26:08
【问题描述】:

我在 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();
    });
}

【问题讨论】:

    标签: angular typescript firebase ionic3 google-cloud-firestore


    【解决方案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'))
      }
    

    当然你应该在另一个函数中打破这个函数,但这会起作用。

    【讨论】:

    • 看起来很不错。我会在接下来的几天里将它应用到我的项目中,如果我有任何问题,我会告诉你。非常感谢您的反馈:)
    • 不客气,如果您发现任何问题,我想知道您的反馈意见并一起努力。
    • 对不起,朋友我仍然没有机会测试这个,因为我非常忙于完成这个项目的第三个里程碑。我们不会在这个 MS 上实现这个功能。但我会在这周内对此进行测试,并让你知道。谢谢。
    猜你喜欢
    • 2021-11-13
    • 2018-12-05
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    • 2017-09-30
    • 1970-01-01
    相关资源
    最近更新 更多