Kotlin сопрограмма с функциями Firebase

У меня возникла проблема с реализацией функции анонимного входа в Firebase с сопрограммой Kotlin.

Ниже приведен код для этого:

Repository.kt

suspend fun getUserId(){
    firebaseHelper.getUserId().collect{
        if (it == "Successful"){
           emit(it)
        } else {
           emit("Task unsuccessful")
        }
    }
}

FirebaseHelper.kt

fun getUserId() = flow {
   val firebaseLoginAsync = Firebase.auth.signInAnonymously().await()
   if (firebaseLoginAsync.user != null && !firebaseLoginAsync.user?.uid.isNullOrEmpty()) {
       emit("Successful")
   } else {
       emit("Failed")
   }
}

Он отлично работает, когда устройство Android подключено к Интернету.
Но когда я тестирую этот код без интернета, он никогда не завершается, то есть выполнение никогда не достигает if else блока FirebaseHelper.kt.

Мне не удалось найти какой-либо ресурс, который помог бы мне понять причину этой проблемы и любое возможное решение.
Одна идея, которую я могу придумать на стороне решения, - принудительно отменить выполнение функций await() через некоторое время, но я не могу найти ничего, связанного с реализацией.

В дополнение к моему ответу, поскольку вы используете Kotlin, я думаю, что этот ресурс может помочь.

Alex Mamo 05.12.2022 09:57
0
1
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Он отлично работает, когда устройство Android подключено к Интернету.

Поскольку для операции аутентификации требуется подключение к Интернету, это ожидаемое поведение.

Но когда я тестирую этот код без Интернета, он никогда не завершается.

Без Интернета вы не сможете получить доступ к серверам Firebase, отсюда и такое поведение. Однако, согласно официальной документации функции await():

Эту функцию приостановки можно отменить. Если Job текущей сопрограммы отменяется или завершается, пока эта приостанавливающая функция ожидает, эта функция немедленно возобновляется с CancellationException.

Или вы можете просто проверить, подключен ли пользователь к Интернету перед выполнением аутентификации.

Привет. Помог ли мой ответ? Могу ли я помочь вам с другой информацией?

Alex Mamo 09.12.2022 08:29
Ответ принят как подходящий

Я заставил это работать с помощью блока try catch и функции withTimeout() в файле FirebaseHelper.kt. Ниже приведен код решения:

fun getUserID() = flow {
        try {
            val signInTask = Firebase.auth.signInAnonymously()
            kotlinx.coroutines.withTimeout(5000) {
                signInTask.await()
            }
            if (signInTask.isSuccessful){
                emit("Successful")
            } else {
                emit("Failed")
            }
        } catch (e: Exception){
            emit("Can't connect to the server\nPlease check your internet connection and retry")
        }
    }

withTimeout(timeMillis: Long, block: suspend CoroutineScope.() -> T) запускает данную приостановку block на timeMillis миллисекунд и сбрасывает TimeoutCancellationException, если превышено время ожидания.

Другие вопросы по теме