I’ve noticed that Firestore doesn’t automatically remove snapshot listeners when a view is dismissed.
For example, in my Login
view, I fetch a list of accounts using a Firestore snapshot listener and pass a completion handler to it. After logging in, when I navigate to the Home
view and add a new account, the completion handler from the Login view still gets triggered.
I know that we can manually remove the snapshot listener, but shouldn’t Firestore automatically remove the snapshot listener when the Login view disappears? Why isn’t this happening?
Additionally, in the Login view, I have a state variable storing some data, and I tried printing it inside the completion handler. I can see that it still holds the data, even though the Login view should have been deallocated.
Why does this listener persist beyond the view’s lifecycle?
2
Answers
When you need to read data in real time from Firestore, you have to attach a persistence listener. This means that if you want to no longer listen to real-time updates, then you have to explicitly detach the listener so that your event callbacks stop getting called. This is necessary because allows your client to stop using the bandwidth. Less bandwidth, less to pay. In Swift it should look like this:
Also remember, a listener isn’t tied in any way to a View. You have to detach it as soon as you that the listener is no longer needed.
Not all listeners need to be tied to a view lifecycle – you have to determine if that’s the case, then implement it properly. For example, you might want to capture updates to a document immediately in the "background" of your app, no matter what the user is doing or looking at. Or, maybe a listener needs to be active through several views so that you don’t unnecessarily query the database on each one.
It’s up to you, the programmer, to determine the right time to remove a listener for your particular use case. If the right times are tied to a view lifecycle, then that’s the code you should write. The Firebase SDK can’t know what you want ahead of time.