为什么在添加单个文档时,Firestore 侦听器返回 .add 两次?



我正在使用谷歌地图,我的用户可以在地图上添加地图标记。 地图标记存储在火堆中。 我有一个侦听数据库的侦听器。 每个用户只能提交一个地图标记 - 因此数据库中每个用户只有一个文档。但是他们可以修改标记的纬度和液化天然气。

我的消防店是:

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集合,并且只在添加新文档时触发一次。

我不确定问题是否是:

  1. 当我离开MapController时,我不会分离听众 ->AddMarkerController
  2. 听众处于viewWillAppear而不是viewDidLoad但从阅读Firebase博客来看,它应该处于viewWillAppear
  3. 无论是每次更改时遍历整个快照的snapshot.documentChanges.forEach

第一个added是调用setData()后立即触发的本地事件。第二个added是服务器写入数据后的确认事件。

请参阅文档中的本地更改事件部分。

另一个原因可能是您无法取消注册观察者。如果在viewWillAppear中注册观察者,则在viewWillDisappearviewDidDisappear中取消注册。如果不这样做,您最终会得到同一事件的多个观察者,从而进行多次调用。

最新更新