Aseem Salim
Aseem Salim

Reputation: 211

Coroutin To Perform task

hi this is my user repository

class UserRepository(private val appAuth: FirebaseAuth) : SafeAuthRequest(){

  suspend fun userLogin(email: String,password: String) : AuthResult{
     return authRequest { appAuth.signInWithEmailAndPassword(email,password)}
  }
}

this is the SafeAuthRequest class

open class SafeAuthRequest {
  suspend fun<T: Any> authRequest(call : suspend () -> Task<T>) : T{

    val task = call.invoke()
    if(task.isSuccessful){
        return task.result!!
    }
    else{
        val error = task.exception?.message
        throw AuthExceptions("$error\nInvalid email or password")
    }
  }
}

calling above things like that

  /** Method to perform login operation with custom  */
fun onClickCustomLogin(view: View){
    authListener?.onStarted()

    Coroutines.main {
        try {
            val authResult = repository.userLogin(email!!,password!!)
            authListener?.onSuccess()
        }catch (e : AuthExceptions){
           authListener?.onFailure(e.message!!)
        }
    }
}

and my authListener like this

interface AuthListener {
  fun onStarted()
  fun onSuccess()
  fun onFailure(message: String)
}

I am getting an error as the task is not completed

is the correct way to implement the task

Upvotes: 1

Views: 96

Answers (1)

AndroidZen
AndroidZen

Reputation: 616

I'm using MVVM architectural pattern, so the example I'm going to provide is called from my ViewModel class, that means I have access to viewModelScope. If you want to run a similar code on Activity class, you have to use the Coroutines scope available for your Activity, for example:

val uiScope = CoroutineScope(Dispatchers.Main)
uiScope.launch {...}

Answering your question, what I've done to retrieve login from user repository is this:

//UserRepository.kt
class UserRepository(private val appAuth: FirebaseAuth) {

    suspend fun userLogin(email: String, password: String) : LoginResult{
        val firebaseUser = appAuth.signInWithEmailAndPassword(email, password).await()  // Do not forget .await()
        return LoginResult(firebaseUser)
    }
}

LoginResult is a wrapper class of firebase auth response.

//ClassViewModel.kt
class LoginFirebaseViewModel(): ViewModel(){
    private val _loginResult = MutableLiveData<LoginResult>()
    val loginResult: LiveData<LoginResult> = _loginResult

    fun login() {
        viewModelScope.launch {
            try {
                repository.userLogin(email!!,password!!).let {
                    _loginResult.value = it
                }
            } catch (e: FirebaseAuthException) {
                // Do something on firebase exception
            }       
        }
    }
}

The code on Activity class would be like this:

// Function inside Activity
fun onClickCustomLogin(view: View){

    val uiScope = CoroutineScope(Dispatchers.Main)
    uiScope.launch {
        try {
            repository.userLogin(email!!,password!!).let {
                authResult = it
            }
        }catch (e : FirebaseAuthException){
            // Do something on firebase exception
        }
    }
}

One of the main benefits of using Coroutines is that you convert asynchronous code in sequential one. That means you don't need listeners or callbacks.

I hope this help you

Upvotes: 1

Related Questions