androidfirebasekotlinkotlin-coroutineskotlin-flow

Why CallbackFlow is running on main thread


I am using callback flow in my code to retrieve data from Firebase Database. Here is my code

 @ExperimentalCoroutinesApi
  suspend fun getUserOrder() = callbackFlow<UserOrder>{
            println("Current Thread name is ${Thread.currentThread().name}")
            databaseReference.child("Order").addValueEventListener(object : ValueEventListener{
                override fun onCancelled(error: DatabaseError) {
                    Log.d("database error ",error.message)
                    channel.close(error.toException())
                }

                override fun onDataChange(snapshot: DataSnapshot) {
                    if (snapshot.exists()){
                        snapshot.children.forEach { data ->
                            data.children.forEach {newData->
                                newData.children.forEach { childData->
                                    val userOrder = UserOrder(
                                        childData.key!!,
                                        childData.child("item_name").value as String,
                                        childData.child("item_price").value as String,
                                        childData.child("item_quantity").value as String,
                                        childData.child("item_weight").value as String
                                    )
                                    offer(userOrder)
                                }
                            }
                        }
                        channel.close()
                    }
                }
            })
        awaitClose()
    } 

//Activity class code
  viewModel.viewModelScope.launch {
        val time = measureTimeMillis {
            viewModel.getOrder().collect {
                println("Item id is ${it.item_id}")
            }
        }
        println("Total time taken is $time")
    }

Data is retrieving but it is running on main thread. I wanna run it on background thread. How is it possible?. Tell me anybody


Solution

  • You launched your coroutine with the viewModelScope, which is "bound to Dispatchers.Main.immediate". That's why your coroutines runs in the main thread.

    To jump threads, you can use withContext.

    The IO dispatcher can be used for thread-blocking calls, which I do not see in the given code.