I'm using Firebase authentication. In the repository I have this function:
override suspend fun signIn(): Result<Boolean> {
return try {
auth.signInAnonymously().await()
Result.Success(true)
} catch (ex: Exception) {
Result.Failure(ex)
}
}
This function is called from within the ViewModel class:
var response by mutableStateOf<Result<Boolean>>(Result.Success(false))
private set
fun signIn() = viewModelScope.launch {
response = repository.signIn()
}
Which works fine but I was suggested to use in the ViewModel:
fun signIn() = viewModelScope.launch(Dispatchers.IO) {
response = repository.signIn()
}
To add Dispatchers.IO
and inside the repository:
override suspend fun signIn(): Result<Boolean> {
return withContext(Dispatchers.IO) {
try {
auth.signInAnonymously().await()
Result.Success(true)
} catch (ex: Exception) {
Result.Failure(ex)
}
}
}
To launch a coroutine using withContext
. I and I don't understand why? I'm using Jetpack Compose.
CodePudding user response:
When you use the viewModelScope by default it starts a coroutine with main dispatcher but, you want to do a service call by using firebase services, then you should change your context to use IO dispatcher to don't block ui. So you use withContext(Dispatchers.IO) block.
CodePudding user response:
Actually, since you are already calling signIn
from a coroutine started with Dispatchers.IO
you don't have to use return withContext(...)
.
Since your repository method is suspend
, it is able to call coroutines without special blocks like withContext
.
// This line tells to launch code on separate IO thread, to avoid UI freezing
// Since default viewModelScope.launch runs on Dispatchers.Main, which is
// also used for rendering
fun signIn() = viewModelScope.launch(Dispatchers.IO) {
response = repository.signIn()
}