Wei
Wei

Reputation: 1037

Is it okay for a ViewModel class implementing LifecycleObserver?

Reading the ViewModel overview, I wonder if it is okay for a ViewModel to simultaneously become a LifecycleObserver too? My point doing that is to disconnect the Firebase listener when user's not interacting with the UI and reconnect it again when the user's interacting with the UI. As far as I have done and know, it works perfectly. But, I'm afraid if it's bad to do so (memory leaks whatsoever). And if so, is there an alternative to that?

class UserProfileViewModel : ViewModel(), LifecycleObserver {
    companion object {
        private const val TAG = "ProfileViewModel"
    }

    private lateinit var mUserProfile: MutableLiveData<DocumentSnapshot>
    private var mRegistration: ListenerRegistration? = null

    override fun onCleared() {
        Log.d(TAG, "onCleared")
        disconnectListener()
    }

    fun getUserProfile(): LiveData<DocumentSnapshot> {
        if (!::mUserProfile.isInitialized) {
            mUserProfile = MutableLiveData()
        }
        return mUserProfile
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun connectListener() {
        Log.d(TAG, "connectListener")
        val user = FirebaseAuth.getInstance().currentUser
        if (user == null) {
            Log.w(TAG, "User not signed in.")
            return
        }
        val firestore = FirebaseFirestore.getInstance()
        val docRef = firestore.collection(UsersContract.COLLECTION_NAME).document(user.uid)
        mRegistration = docRef.addSnapshotListener { snapshot, exception ->
            if (exception != null) {
                Log.w(TAG, "Failed to fetch user data", exception)
                return@addSnapshotListener
            }
            if (snapshot != null && snapshot.exists()) {
                mUserProfile.value = snapshot
            }
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun disconnectListener() {
        Log.d(TAG, "disconnectListener")
        mRegistration?.remove()
        mRegistration = null
    }
}

Upvotes: 10

Views: 1838

Answers (1)

Karthi Keyan
Karthi Keyan

Reputation: 159

If you are not concerned about having the listeners scoped to resume/pause. You can achieve this with a custom live data. You can have a custom livedata like UserProfileLiveData which extends livedata.

Refer to Extend Live Data - https://developer.android.com/topic/libraries/architecture/livedata#extend_livedata

Upvotes: 5

Related Questions