Решение с использованием onDataChange для проверки значения (база данных Firebase и аутентификация Firebase) - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь проверить аутентификацию, используя роль пользователя, поэтому я установил логическое значение, чтобы проверить, является ли роль пользователя «тренером» или «стажером».Но onDataChange изменяет логическое значение только после намерения ...

private lateinit var auth: FirebaseAuth
private lateinit var firebaseDatabase: FirebaseDatabase
private lateinit var databaseReference: DatabaseReference
var trainer:Boolean = false

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_login)
    auth = FirebaseAuth.getInstance()
    firebaseDatabase = FirebaseDatabase.getInstance()
    databaseReference = firebaseDatabase.getReference("users")

    backRegister.setOnClickListener {
        val intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
    }

    btnSignIn.setOnClickListener {
        val email = etEmail.text.toString()
        val pass = etPass.text.toString()
        login(email, pass)
    }
}

fun login(email:String, pass:String){
    auth.signInWithEmailAndPassword(email, pass)
        .addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                val user = auth.currentUser
                if (user != null) {
                    checkRole(user)
                    if(trainer){
                        intent = Intent(this, HomeTrainer::class.java)
                        Toast.makeText(baseContext, "Welcome Trainer",
                            Toast.LENGTH_SHORT).show()
                        startActivity(intent)
                    }
                    else {
                        var intent = Intent(this, Home::class.java)
                        Toast.makeText(baseContext, "Welcome Trainee",
                            Toast.LENGTH_SHORT).show()
                        startActivity(intent)
                    }
                }
            } else {
                Toast.makeText(baseContext, "Login Failed",
                    Toast.LENGTH_SHORT).show()
            }
        }
}

fun checkRole(user:FirebaseUser){
    val postListener = object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            for (datas in dataSnapshot.children) {
                if (datas.key.toString() == user.uid) {
                    trainer = false
                    if (datas.child("role").getValue().toString().trim().equals("trainer")) {
                        trainer = true
                    }
                }
            }
        }
        override fun onCancelled(databaseError: DatabaseError) {
        }
    }
    databaseReference.addValueEventListener(postListener)
}

1 Ответ

0 голосов
/ 26 января 2019

API Firebase имеют значение asynchronous, что означает, что функция onDataChange() возвращается сразу после ее вызова, и обратный вызов из задачи, которую она возвращает, будет вызван через некоторое время.Там нет никаких гарантий о том, сколько времени это займет.Таким образом, получение этих данных может занять от нескольких сотен миллисекунд до нескольких секунд.Поскольку этот метод немедленно возвращается, значение вашей переменной trainer, которую вы пытаетесь использовать, еще не будет заполнено из обратного вызова.Поэтому простое создание его в качестве глобальной переменной не поможет, и его значение всегда будет false.

По сути, вы пытаетесь использовать значение синхронно из асинхронного API.Это не очень хорошая идея.Вы должны обрабатывать API-интерфейсы асинхронно, как и предполагалось.

Для быстрого решения этой проблемы можно использовать значение вашей bool переменной only внутри обратного вызова, в противном случае я рекомендую вам просмотретьпоследняя часть моего ответа от этого поста , в котором я объяснил, как это можно сделать с помощью пользовательского обратного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...