如何在本地范围内分离监听器?
how to detach a listener in a local scope?
我想在按下按钮时分离 viewController 中的 snapshotListener
。我正在阅读其他堆栈溢出问题和文档,他们在同一函数中为侦听器调用 remove 方法。我尝试在我的情况下这样做,但我的 snapshotListener 根本没有工作。
这是我要调整的函数和代码块。
@objc func doneTapped() {
let updateListener = db.collection("school_users/\(user?.uid)/events").whereField("event_name", isEqualTo: navigationItem.title).addSnapshotListener(includeMetadataChanges: true) { (querySnapshot, error) in
if let error = error {
print("There was an error fetching the documents: \(error)")
} else {
self.eventName = querySnapshot!.documents.map { document in
return EventName(eventName: (document.get("event_name") as! String))
}
self.db.document("school_users/\(self.user?.uid)/events/\(self.docIDUneditableTextF.text!)").updateData(["event_date": self.dateEditableTextF.text, "event_cost": self.costEditableTextF.text, "for_grades": self.gradesEditableTextF.text]) { (error) in
if let error = error {
print("There was an error updating the document: \(error)")
} else {
print("The document was successfully updated."
}
}
}
}
dateEditableTextF.resignFirstResponder()
dateEditableTextF.isEnabled = false
costEditableTextF.resignFirstResponder()
costEditableTextF.isEnabled = false
gradesEditableTextF.resignFirstResponder()
gradesEditableTextF.isEnabled = false
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editTapped))
}
我尝试调用 updateListener.remove()
但它使我的 snapshotListener 根本无法工作,而且当文档更新时,打印语句永远不会结束,这是否也是因为监听器仍然处于活动状态或者是不同的问题?
addSnapshotListener
会在数据发生变化时为您提供更新。我不清楚您为什么要立即删除侦听器,如果您真的想接收更新——而且,正如您所指出的,立即删除它基本上会导致它根本无法运行。也许 post link 给其中一些 posts/documentation 你看到了你正在引用的代码并且有人可以深入了解正在发生的事情。
我怀疑您实际上不需要更新数据。在这种情况下,您可以只使用 .getDocuments()
代替。请在此处查看有关获取数据的不同方式的 Firestore 文档:https://firebase.google.com/docs/firestore/query-data/get-data
第二个问题(无限打印)与第一个有关。因为你有一个侦听器,它会在数据更改时 return 更新,当你进行第二次数据库调用(你的 updateData
)时,它会更新你的数据,再次触发侦听器。这将继续循环,因为他们将继续互相呼叫。这是另一个迹象,表明您可能实际上并不需要侦听器,而是需要一次调用来获取数据。如果您确实确实想要更新,则必须找到一种方法来分离您的第二个请求,以免陷入循环。
根据评论更新:(在不同函数中删除监听器的示例)
在您的视图、视图控制器等上,为侦听器声明一个 属性:
class MyViewController : UIViewController {
private var documentListener: ListenerRegistration? //assuming that ListenerRegistration is the correct type here, but you can check the current type of your updateListener to check
}
然后,在您的函数中,将您的侦听器设置为:
documentListener = db.collection("school_users/\(user?.uid)/events").whereField("event_name", isEqualTo: navigationItem.title).addSnapshotListener()...
然后,稍后(如 viewDidDisappear
),您可以删除它:
documentListener?.remove()
我想在按下按钮时分离 viewController 中的 snapshotListener
。我正在阅读其他堆栈溢出问题和文档,他们在同一函数中为侦听器调用 remove 方法。我尝试在我的情况下这样做,但我的 snapshotListener 根本没有工作。
这是我要调整的函数和代码块。
@objc func doneTapped() {
let updateListener = db.collection("school_users/\(user?.uid)/events").whereField("event_name", isEqualTo: navigationItem.title).addSnapshotListener(includeMetadataChanges: true) { (querySnapshot, error) in
if let error = error {
print("There was an error fetching the documents: \(error)")
} else {
self.eventName = querySnapshot!.documents.map { document in
return EventName(eventName: (document.get("event_name") as! String))
}
self.db.document("school_users/\(self.user?.uid)/events/\(self.docIDUneditableTextF.text!)").updateData(["event_date": self.dateEditableTextF.text, "event_cost": self.costEditableTextF.text, "for_grades": self.gradesEditableTextF.text]) { (error) in
if let error = error {
print("There was an error updating the document: \(error)")
} else {
print("The document was successfully updated."
}
}
}
}
dateEditableTextF.resignFirstResponder()
dateEditableTextF.isEnabled = false
costEditableTextF.resignFirstResponder()
costEditableTextF.isEnabled = false
gradesEditableTextF.resignFirstResponder()
gradesEditableTextF.isEnabled = false
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editTapped))
}
我尝试调用 updateListener.remove()
但它使我的 snapshotListener 根本无法工作,而且当文档更新时,打印语句永远不会结束,这是否也是因为监听器仍然处于活动状态或者是不同的问题?
addSnapshotListener
会在数据发生变化时为您提供更新。我不清楚您为什么要立即删除侦听器,如果您真的想接收更新——而且,正如您所指出的,立即删除它基本上会导致它根本无法运行。也许 post link 给其中一些 posts/documentation 你看到了你正在引用的代码并且有人可以深入了解正在发生的事情。
我怀疑您实际上不需要更新数据。在这种情况下,您可以只使用 .getDocuments()
代替。请在此处查看有关获取数据的不同方式的 Firestore 文档:https://firebase.google.com/docs/firestore/query-data/get-data
第二个问题(无限打印)与第一个有关。因为你有一个侦听器,它会在数据更改时 return 更新,当你进行第二次数据库调用(你的 updateData
)时,它会更新你的数据,再次触发侦听器。这将继续循环,因为他们将继续互相呼叫。这是另一个迹象,表明您可能实际上并不需要侦听器,而是需要一次调用来获取数据。如果您确实确实想要更新,则必须找到一种方法来分离您的第二个请求,以免陷入循环。
根据评论更新:(在不同函数中删除监听器的示例)
在您的视图、视图控制器等上,为侦听器声明一个 属性:
class MyViewController : UIViewController {
private var documentListener: ListenerRegistration? //assuming that ListenerRegistration is the correct type here, but you can check the current type of your updateListener to check
}
然后,在您的函数中,将您的侦听器设置为:
documentListener = db.collection("school_users/\(user?.uid)/events").whereField("event_name", isEqualTo: navigationItem.title).addSnapshotListener()...
然后,稍后(如 viewDidDisappear
),您可以删除它:
documentListener?.remove()