2

Here is my login function that return a flow

override  fun loginMeIn(loginDto: LoginDto): Flow<Resource<User?>> = flow {
    emit(Resource.Loading())

    try {
        Log.e(TAG, "loginMeIn : try");
        val result = api.loginMeIN(loginDto)
          dao.deleteAll()
          dao.upsertUser(result.toUserEntity())
         val user = dao.getUsers().first()
        emit(Resource.Success<User?>(user.toUser()))
        Log.e(TAG, "loginMeIn : job finished");

    }catch (e:HttpException ){
        emit(Resource.Error<User?>(message = e.response().toString(),data = null))
        Log.e(TAG, "loginMeIn :"+ e);

    }catch (e:IOException){

        emit(Resource.Error<User?>(message = "Couldn't reach server, check Your internet connection",data = null))
        Log.e(TAG, "Couldn't reach server");
    }

}

with this implementation the app crash with error : Cannot access database on the main thread and if i use coroutine scope for IO dispatchers i cant emit the Success result Please Help!

1 Answers1

0

You can switch coroutine context to Dispatchers.IO when making DB requests:

val user = withContext(Dispatchers.IO) {
    dao.deleteAll()
    dao.upsertUser(result.toUserEntity())
    dao.getUsers().first()
}
emit(Resource.Success<User?>(user.toUser()))

If you use Room DB you can try to mark functions as suspend, for example:

// in Dao class
@Insert
suspend fun insertUser(user: User)

If all function are marked as suspend then you won'y need to switch coroutine context to Dispatchers.IO in flow builder.

Sergio
  • 27,326
  • 8
  • 128
  • 149