Почему в этой функции переменная не обновляется и не возвращается правильно? - PullRequest
0 голосов
/ 10 июля 2020

Итак, я слежу за видео и документацией Google, пытаясь реализовать вход пользователя с помощью Firebase в приложении android. Это работает, поэтому, чтобы попытаться привести в порядок (и помочь мне повторно использовать код в другом проекте), у меня есть много кода входа в систему, перемещенного в отдельный файл .kt, и я использовал приведенную ниже функцию для создания нового пользователя.

//in LoginActivity.kt
fun createNewUser(email:String, password:String) :Boolean{
        var success:Boolean = false

        auth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    
                    success = true
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(null, "createUserWithEmail:success")
                    val user = auth.currentUser
                    //updateUI(user)
                    
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(null, "createUserWithEmail:failure", task.exception)
                    //Toast.makeText(baseContext, "Authentication failed.",Toast.LENGTH_SHORT).show()
                    //updateUI(null)
                    success = false
                }               
            }

        return success
    }

Проблема, с которой я столкнулся, заключается в том, что логическое значение «success» не обновляется при создании учетной записи, журнал с сообщением «Success», похоже, работает нормально. Я попытался изменить начальное состояние success с false на true, и это вернуло true, как ожидалось, и мой код, смотрящий на результат этого, работал нормально.

Вот где он вызывается from, как я уже сказал, тосты работают нормально, но возвращается значение success всегда то, как оно было инициализировано.

//in MainActivity.kt
var login = LoginActivity()
            if(login.createNewUser(email,password)) {
                Toast.makeText(this,"I got this far",Toast.LENGTH_SHORT).show()
                uploadImageToFirebase()
            }
            else{
                Toast.makeText(this,"I didnt get this far",Toast.LENGTH_SHORT).show()
            }

Спасибо за любую помощь :)

1 Ответ

1 голос
/ 10 июля 2020

Я начну с конца, потому что это огромная ошибка:

var login = LoginActivity()

Никогда не создавайте экземпляр Activity. Создание экземпляров активности обрабатывается операционной системой. Если createNewUser полагается на какие-либо функции LoginActivity, тогда он завершится ошибкой при вызове вашего собственного экземпляра. И если он не полагается на них, то не определяйте его внутри LoginActivity.

Относительно вашего основного вопроса:

Когда вы передаете обратный вызов функции, это означает, что работает асинхронно. Обратный вызов будет вызываться когда-нибудь в будущем, после того, как эта функция уже вернется. Итак, createNewUser не может вернуть результат обратного вызова.

Вместо этого вы можете создать свой собственный обратный вызов для своей функции следующим образом. Я рассматриваю auth.currentUser как тип User, но вы должны указать любой класс, которым он является на самом деле.

fun createNewUser(email:String, password:String, onComplete: (User?) -> Unit) {
        auth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(null, "createUserWithEmail:success")
                    onComplete(auth.currentUser)
                    
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(null, "createUserWithEmail:failure", task.exception)
                    onComplete(null)
                }               
            }
    }

Затем, чтобы использовать его, вы можете вызвать функцию и в своем обратном вызове лямбда вы можете отреагировать в зависимости от того, является ли пользователь нулевым или нет, что указывает на неудачу или успех:

createNewUser(email, password) { user ->
    if (user != null) {
        // success. Do something with the smart-casted non-null user variable
    } else {
        // failure. Show error message to the user, etc.
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...