繁体   English   中英

如何在执行任务之前等待多个 firebase 查询完成?

[英]How to wait for multiple firebase queries to finish before executing a task?

我试图弄清楚如何删除所有已保存的用户数据,一旦删除该数据,在调用 deleteUserAccount() 时注销用户并删除他们的帐户。

现在,当用户按下“删除帐户”按钮时,他们的帐户被删除,但数据仍保留在 firebase 上,因为完成处理程序在 deleteAllUserTicketData() 之前被调用 function 有足够的时间来执行查询并删除相应的文档.

我的问题是,如何在执行完成处理程序之前等待查询执行和所有文档被删除,以便注销用户并删除他们的帐户?

非常感激! 先谢谢了!

        func deleteAllUserTicketData(completion: @escaping () -> Void) {
            self.rootWsrCollection?.whereField("uid", isEqualTo: userIdRef).addSnapshotListener { (querySnapshot, err) in
                guard let snapshot = querySnapshot else { return }
                for wsr in snapshot.documents{
                    print("Deleting WSR's")
                    self.rootWsrCollection!.document(wsr.documentID).delete()
                }
            }
    
            self.rootExerciseCollection?.whereField("uid", isEqualTo: userIdRef).addSnapshotListener { (querySnapshot, err) in
                guard let snapshot = querySnapshot else { return }
                for exercise in snapshot.documents {
                    print("Deleting Exercises")
                    self.rootExerciseCollection!.document(exercise.documentID).delete()
                }
            }
    
            self.rootWorkoutsCollection?.whereField("uid", isEqualTo: userIdRef).addSnapshotListener { (querySnapshot, err) in
                guard let snapshot = querySnapshot else { return }
                for workout in snapshot.documents {
                    print("Deleting Workouts")
                    self.rootWorkoutsCollection!.document(workout.documentID).delete()
                }
            }
    
            self.workoutsCollection.daysCollection.removeAll()
            completion()
        }
    


        func deleteUserFromFirestore(completion: @escaping () -> Void) {
            self.rootUserCollection?.whereField("uid", isEqualTo: userIdRef).addSnapshotListener { (querySnapshot, err) in
                guard let snapshot = querySnapshot else { return }
                for user in snapshot.documents {
                    self.rootUserCollection!.document(user.documentID).delete()
                }
                completion()
            }
        }


    
        func deleteUserAccount() {
            deleteAllUserTicketData {
                self.deleteUserFromFirestore {
                    Auth.auth().currentUser?.delete()
                }
            }
        }

您可以尝试DispatchGroup等待所有异步,然后在它们全部完成时触发。 如果enter() 5 次,还需要leave() 5 次。 您需要平衡leave()enter() 如果你调用leave()多于enter() ,它会因为不平衡调用而崩溃。

而且,如果您不需要实时观察者,请不要使用 addSnapShotListener。 改用这个https://firebase.google.com/docs/firestore/query-data/get-data#get_a_document

这是您更新的逻辑:

        func deleteAllUserTicketData(completion: @escaping () -> Void) {
            let dispatchGroup = DispatchGroup()

            dispatchGroup.enter()
            self.rootWsrCollection?.whereField("uid", isEqualTo: userIdRef).addSnapshotListener {[weak self] (querySnapshot, err) in
                guard let snapshot = querySnapshot else { return }
                for wsr in snapshot.documents{
                    print("Deleting WSR's")
                    self?.rootWsrCollection!.document(wsr.documentID).delete()
                    // use can try this for shortened call
                    wsr.delete()
                }
                // Suppose that delete() is success
                dispatchGroup.leave()
            }

            dispatchGroup.enter()
            self.rootExerciseCollection?.whereField("uid", isEqualTo: userIdRef).addSnapshotListener {(querySnapshot, err) in
                guard let snapshot = querySnapshot else { return }
                for exercise in snapshot.documents {
                    print("Deleting Exercises")
                    exercise.delete()
                }
                dispatchGroup.leave()
            }

            dispatchGroup.enter()
            self.rootWorkoutsCollection?.whereField("uid", isEqualTo: userIdRef).addSnapshotListener { (querySnapshot, err) in
                guard let snapshot = querySnapshot else { return }
                for workout in snapshot.documents {
                    print("Deleting Workouts")
                    workout.delete()
                }
                dispatchGroup.leave()
            }
            
            // When no waiting item remains (all entered and left), this block will be triggered on queue, in this case, is it Global queue (like background thread
            // So if you need to update UI from this, you need to switch to Main Queue or DispatchQueue.main.async { }
            dispatchGroup.notify(queue: DispatchQueue.global()) { [weak self] in
                // refer to self with a weak reference to avoid retain cycle, prevent memory leak
                self?.workoutsCollection.daysCollection.removeAll()
                completion()
            }
        }

        func deleteUserFromFirestore(completion: @escaping () -> Void) {
            self.rootUserCollection?.whereField("uid", isEqualTo: userIdRef).addSnapshotListener { (querySnapshot, err) in
                guard let snapshot = querySnapshot else { return }
                for user in snapshot.documents {
                    user.delete()
                }
                completion()
            }
        }
    
        func deleteUserAccount() {
            self.deleteAllUserTicketData { [weak self] in
                self?.deleteUserFromFirestore {
                    Auth.auth().currentUser?.delete()
                }
            }
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM