Reputation: 1997
I'm trying to optimise the performances in my app and I noticed that I do not remove Firestore listeners from my repository.
My repository has a number of functions that return a LiveData
, that is then observed via Transformations from ViewModels
and then the views.
One-time operations work absolutely fine (upload, delete etc.) but permanent listeners don't get garbage collected when the activity finishes.
Right now the function inside the repository looks like this:
// [...]
class Repository {
// [...]
fun retrieveCode() {
val observable = MutableLiveData<Code>()
val reference =
FirebaseFirestore.getInstance().collection(/**/).document(/**/)
reference
.addSnapshotListener { snapshot, exception ->
if(exception != null) {
observable.value = null
}
if(snapshot != null {
observable.value = snapshot.//[convert to object]
}
}
return observable
}
}
I found a workaround which is to create a custom LiveData
object that handles the listener removal when it becomes inactive, like this:
class CodeLiveData(private val reference: DocumentReference):
LiveData<Code>(), EventListener<DocumentSnapshot>{
private var registration: ListenerRegistration? = null
override fun onEvent(snapshot: DocumentSnapshot?,
exception: FirebaseFirestoreException?) {
if(exception != null) {
this.value = null
}
if(snapshot != null) {
this.value = snapshot.//[convert to object]
}
}
override fun onActive() {
super.onActive()
registration = reference.addSnapshotListener(this)
}
override fun onInactive() {
super.onInactive()
registration?.remove()
}
}
Is there a way to solve this problem without creating a custom class, but rather by improving a function similar to the first example?
Thanks,
Emilio
Upvotes: 3
Views: 4455
Reputation: 138824
There are two ways in which you can achieve this. The first one would be to stop listening for changes and this can be done in your onStop()
function by calling remove()
function on your ListenerRegistration
object like this:
if (registration != null) {
registration.remove();
}
The approach would be to you pass your activity as the first argument in the addSnapshotListener()
function, so Firestore can clean up the listeners automatically when the activity is stopped.
var registration = dataDocumentReference
.addSnapshotListener(yourActivity, listener)
Upvotes: 7