Reputation: 131
I have this app where I am implementing a logout feature with firebase firestore. What I want to do is detach all my snapshotListeners when the user logs out. I use an environmentObject to observe when the user logged out.
class StatusManager: ObservableObject{
@Published var didLogOut: Bool = false
}
I inject the object into the environment. Then, I catch the object in every view that has a listener.
@EnvironmentObject var statusManager: StatusManager
This is how I plan to detach the listener once the user logs out.
.onAppear(perform: {
if statusManager.didLogOut == false{
notifyListener = db.collectionGroup("resources").whereField("control", isEqualTo: true).addSnapshotListener { (snapshot, err) in
//All the functionality
}
}
else{
notifyListener?.remove()
}
})
And this is where the user logs out.
Button(action: {
isLoggedIn = false
lastLoggedEmail = ""
lastLoggedUserType = ""
lastLoggedUserPassword = ""
statusManager.didLogOut = true
try? Auth.auth().signOut()
navStack.pop(to: .root)
}, label: {
Text("Sign Out")
.font(Font.custom("Roboto-Light", size: 14))
})
The problem is, The code where I use the snapshot listener is never reread once the didLogOut state is changed. Therefore, the snapshot listener is never removed.
Upvotes: 1
Views: 457
Reputation: 310
If the view where your notifyListener logic is not re-drawn (as in removed from the tree and re-added again) that code will only run once (when it's shown for the first time, since it's an onAppear block). If that's the case you can use the onChange block instead.
.onChange(of: statusManager.didLogOut) { value
if value == false {
notifyListener = db.collectionGroup("resources").whereField("control", isEqualTo: true).addSnapshotListener { (snapshot, err) in }
} else {
notifyListener?.remove()
}
})
Upvotes: 1