Home > Net >  Firebase Auth with Kotlin Flow
Firebase Auth with Kotlin Flow

Time:09-06

I am learning clean architecture and Kotlin Flow. I want to check is user mail exists in the Firebase Auth base. However, when I threw an error to the flow function, app is crash.

CheckUserUseCase.kt

class CheckUserUseCase @Inject constructor(private val repository: SignInRepository) {
    operator fun invoke(mail: String): Flow<Status<Boolean, String>> = flow {
        emit(Status.Loading(data = null))

        try {
            repository.isUserExists(mail = mail)
            emit(Status.Success(data = true))
        } catch (e: Exception) {
            emit(Status.Error(message = e.message, data = false))
        }
    }
}

SignInRepository.kt

interface SignInRepository {
    suspend fun isUserExists(mail: String)
}

SignInRepositoryImpl.kt

class SignInRepositoryImpl @Inject constructor(private val firebaseUserActions: FirebaseUserActions) : SignInRepository {
    override suspend fun isUserExists(mail: String) {
        firebaseUserActions.isUserExists(mail = mail)
    }
}

FirebaseAuthentication.kt

class FirebaseAuthentication @Inject constructor(private val auth: FirebaseAuth) : FirebaseUserActions {
    override suspend fun isUserExists(mail: String){
        auth.fetchSignInMethodsForEmail(mail).addOnCompleteListener { task ->
            task.result.signInMethods?.let {
                if (it.size != 0) Log.i("App.tag", "True.")
                else throw IOException() <-- Crash point.
            }
        }.addOnFailureListener { e -> e.printStackTrace() }
            .await()
    }
}

How can I return a state to Kotlin Flow method? Thank you!

CodePudding user response:

Please try the following approach:

override suspend fun isUserExists(mail: String): Status {
    return try {
        val result = auth.fetchSignInMethodsForEmail(mail).await()
        result.signInMethods?.let {
            if (it.isNotEmpty()) {
                Status.Success(data = true)
            } else {
                Status.Error(message = "No data", data = false)
            }
        } ?: Status.Error(message = "No Data", data = false)
    } catch (e: Exception) {
        Status.Error(message = e.message, data = false)
    }
}

In CheckUserUseCase class just emit the result of calling isUserExists():

emit(Status.Loading(data = null))
emit(repository.isUserExists(mail = mail))

CodePudding user response:

Show crash logs, where exactly on what line it crashes.

EDIT: Try

it.size != 0 && it.size != null

and

if (task.isSuccessful()) {
[...]
     task.result.signInMethods?.let {
[...]
}
  • Related