[英]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.