Reputation: 1331
I'm using google maps and my users can add a map marker to the map. The map markers are stored in firestore. I have a listener that listens in to the database. Each user can only submit one map marker - so there is only one document for each user in the database. But they can modify the lat and lng of their marker.
My firestore is set out as:
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")
}
}
}
}
At the moment for debugging I only have one user in firestore and one document under submittedMarkers
-> {fireauthId}
.
When my app loads the single marker that currently exists is added to the map along with a single print statement "added". So that works.
Here is the problem I've encountered.
When a new user registers and gets a fireauth id they can then go and add a marker from the AddMarkerController
. When they submit the marker i use an unwind segue to get them back to the MapController
. (I don't detach the listener at any stage from the 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 {
}
}
But what I have found is that when they have come back to the MapController
the if (diff.type == .added)
is executed twice and print("added") happens twice even though the currentuser fireauth id is added just the once under the collection submittedMarkers
.
And when I print out the diff.document.ID
i'm getting both the fireauth id of the user who was already in firestore and the current user who just added a new document.
I suspect I don't quite get then how the listener works. I thought if(diff = .added)
would listen to the submittedMarkers
collection and only fire once when a new document is added.
I wasn't sure if the issue is:
MapController
-> AddMarkerController
?viewWillAppear
and not viewDidLoad
but from reading the firebase blog it should be in viewWillAppear
snapshot.documentChanges.forEach
which is looping through the entire snapshot each time something changesUpvotes: 1
Views: 7739
Reputation: 598847
The first added
is the local event that is fired as soon as you call setData()
. The second added
is the acknowledged event after the server has written the data.
See the events for local changes section in the documentation.
Another reason might be that you fail to unregister your observer. If you register your observer in viewWillAppear
, unregister it in viewWillDisappear
or viewDidDisappear
. If you don't, you'll end up with multiple observers for the same event and thus with multiple invocations.
Upvotes: 4