![](/img/trans.png)
[英]How do I wait for an async function to finish executing before rendering a widget in Flutter
[英]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.