簡體   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