我使用谷歌地图,我的用户可以在地图上添加地图标记。 地图标记存储在firestore中。 我有一个监听数据库的监听器。 每个用户只能提交一个地图标记 - 因此数据库中每个用户只有一个文档。但是他们可以修改标记的lat和lng。
我的火店名列如下:
root
- submittedMarkers (collection)
- fireauthID_1 (document)
- field 1 (lat):
- field 2 (lng):
- fireauthID_2 (document)
- field 1 (lat):
- field 2 (lng):
// MapController.swift
override func viewWillAppear(_ animated: Bool){
listener = db.collection("submittedMarkers").addSnapshotListener { querySnapshot, error in
guard let snapshot = querySnapshot else {
print("Error fetching snapshots: \(error!)")
return
}
snapshot.documentChanges.forEach { diff in
if (diff.type == .added){
print("added")
}
if(diff.type == .modified) {
print("modified the document in firestore")
}
}
}
}
目前进行调试时,我只在firestore中有一个用户,在submittedMarkers
下有一个文档 - > {fireauthId}
。
当我的应用加载时,当前存在的单个标记会与单个打印语句一起添加到地图中并添加"。这样才有用。
这是我遇到的问题。
当新用户注册并获得fireauth id时,他们可以从AddMarkerController
添加标记。当他们提交标记时,我使用展开segue将其返回MapController
。 (我不会在MapController
)的任何阶段将听众分开。
// AddMarkerController
docref = db.collection("submittedMarkers").document(currentUserId)
docref?.setData([
"latitude": latitude,
"longitude": longitude,
"date_time": date!,
"distance": dist,
"speed": speed
], options: SetOptions.merge()) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
}
}
但我发现,当他们回到MapController
时,if (diff.type == .added)
被执行两次并且打印("添加")发生两次,即使当前用户fireauth id仅在集合submittedMarkers
下添加一次。
当我打印出diff.document.ID
时,我同时获得已经在firestore中的用户的fireauth id和刚添加新文档的当前用户。
我怀疑我不太了解听众是如何工作的。我认为if(diff = .added)
会收听submittedMarkers
集合,只会在添加新文档时触发一次。
我不确定问题是:
MapController
- >时,我不会分离听众。 AddMarkerController
?viewWillAppear
而不是viewDidLoad
,但是在阅读firebase博客时,它应位于viewWillAppear
snapshot.documentChanges.forEach
循环遍历整个快照答案 0 :(得分:3)
第一个added
是您拨打setData()
后立即触发的本地事件。第二个added
是服务器写入数据后的确认事件。
请参阅文档中的events for local changes部分。
另一个原因可能是您无法取消注册您的观察者。如果您在viewWillAppear
注册观察者,请在viewWillDisappear
或viewDidDisappear
中取消注册。如果你不这样做,你最终将会有多个观察者参加同一个活动,因此会有多次调用。