Search code examples
androidkotlinfirebase-realtime-databaseandroid-livedataandroid-architecture-components

What is the best practice for starting a new thread when using Firebase Realtime Database?


I'm following along this blog for using Android Architecture Components with Firebase Realtime Database. Currently, I am at the part of the blog where I move the LiveData callbacks to onChanged() onto a different thread.

This is what I have (the Kotlin equivalent of the Java code from the blog):

private val uid = Firebase.auth.currentUser!!.uid
private val USERS_REF: DatabaseReference = FirebaseDatabase.getInstance().getReference("/users/$uid")
private val liveData: FirebaseQueryLiveData = FirebaseQueryLiveData(USERS_REF)
private val usersLiveData: MediatorLiveData<Users> = MediatorLiveData()

fun UsersViewModel() {
    usersLiveData.addSource(liveData, object : Observer<DataSnapshot> {
        override fun onChanged(dataSnapshot: DataSnapshot?) {
            if (dataSnapshot != null) {
                Thread(Runnable() {
                    run() {
                        usersLiveData.postValue(dataSnapshot.getValue(Users::class.java))
                    }
                }).start()
            } else {
                usersLiveData.value = null
            }
        }
    })
}

In the blog, it states that the way it has shown to start up a new thread is not considered the "best practice" for starting another thread in a production app. The suggestion is to use an Executor with a pool of reusable threads for a job like this.

How do I modify the current Runnable Thread so that it uses an optimal practice for starting a new thread?


Solution

  • You don't need a new thread at all here. Just remove it.

    postValue() is asynchronous and doesn't block anything. You can call it safely on the main thread. Any LiveData observers will get the value immediately after the database callback completes.