I'm losing my mind over this bug I'm having with Firestore and storing Date
values. Please help.
My data flow works like this:
class DrinkRepository: ObservableObject {
let db = Firestore.firestore().collection("drinks")
@Published var drinks = [Drink]()
init() {
loadData()
}
func loadData() {
let userId = Auth.auth().currentUser?.uid
db
.whereField("userId", isEqualTo: userId as Any)
.addSnapshotListener { (querySnapshot, error) in
if let querySnapshot = querySnapshot {
self.drinks = querySnapshot.documents.compactMap { document in
try? document.data(as: Drink.self)
}
}
}
}
func addDrink(_ drink: Drink) {
do {
var addedDrink = drink
addedDrink.userId = Auth.auth().currentUser?.uid
let _ = try db.addDocument(from: addedDrink)
} catch {
fatalError("Unable to encode drink: \(error.localizedDescription)")
}
}
func updateDrink(_ drink: Drink) {
if let drinkID = drink.id {
do {
try db.document(drinkID).setData(from: drink)
} catch {
fatalError("Unable to encode drink: \(error.localizedDescription)")
}
}
}
}
class DrinkListViewModel: ObservableObject {
@Published var drinkRepository = DrinkRepository()
@Published var drinkVMs = [DrinkViewModel]()
var subscriptions = Set<AnyCancellable>()
init() {
drinkRepository.$drinks
.map { drinks in
drinks.map { drink in
DrinkViewModel(drink: drink)
}
}
.assign(to: \.drinkVMs, on: self)
.store(in: &subscriptions)
}
}
class DrinkViewModel: ObservableObject, Identifiable {
@Published var drinkRepository = DrinkRepository()
@Published var drink: Drink
var id = ""
private var cancellables = Set<AnyCancellable>()
init(drink: Drink) {
self.drink = drink
$drink
.compactMap { drink in
drink.id
}
.assign(to: \.id, on: self)
.store(in: &cancellables)
$drink
.debounce(for: 1, scheduler: RunLoop.main)
.sink { drink in
self.drinkRepository.updateDrink(drink)
}
.store(in: &cancellables)
}
}
When I create a new Drink it works fine but when I create a second one it gets stuck in an endless update loop between Firestore and my app.
This is only when storing a Date
value in my Drink
objects. If I omit the time
value there is no issue. The same thing occurs if I opt to use a Timestamp
value through @ServerTimestamp
.
There is also no issue if I remove the .sink in the DrinkViewModel
.
Any and all tips on what the issue might be or how I can find it would be greatly appreciated.