Reputation: 211
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
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