我正在使用谷歌地图,我的用户可以在地图上添加地图标记。 地图标记存储在火堆中。 我有一个侦听数据库的侦听器。 每个用户只能提交一个地图标记 - 因此数据库中每个用户只有一个文档。但是他们可以修改标记的纬度和液化天然气。
我的消防店是:
root
- submittedMarkers (collection)
- fireauthID_1 (document)
- field 1 (lat):
- field 2 (lng):
- fireauthID_2 (document)
- field 1 (lat):
- field 2 (lng):
地图控制器.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
分离)。
添加标记控制器
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)
被执行两次,print("添加")发生两次,即使当前用户fireauth id只在集合submittedMarkers
下添加一次。
当我打印出diff.document.ID
时,我同时获得了已经在 firestore 中的用户的 fireauth ID 和刚刚添加新文档的当前用户的 fireauth ID。
我怀疑我不太明白听众是如何工作的。我以为if(diff = .added)
会听submittedMarkers
集合,并且只在添加新文档时触发一次。
我不确定问题是否是:
- 当我离开
MapController
时,我不会分离听众 ->AddMarkerController
? - 听众处于
viewWillAppear
而不是viewDidLoad
但从阅读Firebase博客来看,它应该处于viewWillAppear
- 无论是每次更改时遍历整个快照的
snapshot.documentChanges.forEach
第一个added
是调用setData()
后立即触发的本地事件。第二个added
是服务器写入数据后的确认事件。
请参阅文档中的本地更改事件部分。
另一个原因可能是您无法取消注册观察者。如果在viewWillAppear
中注册观察者,则在viewWillDisappear
或viewDidDisappear
中取消注册。如果不这样做,您最终会得到同一事件的多个观察者,从而进行多次调用。