【问题标题】:Solution using onDataChange to Verify Value (Firebase Database & Firebase Auth)使用 onDataChange 验证值的解决方案(Firebase 数据库和 Firebase Auth)
【发布时间】:2019-01-25 18:18:16
【问题描述】:

我正在尝试使用用户的角色来验证身份验证,因此我设置了一个布尔值来检查用户的角色是“培训师”还是“学员”。但是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)
}

【问题讨论】:

    标签: android firebase android-studio kotlin


    【解决方案1】:

    Firebase API 是 asynchronous,这意味着 onDataChange() 函数在调用后会立即返回,并且它返回的任务的回调将在稍后调用。无法保证需要多长时间。因此,数据可用可能需要几百毫秒到几秒钟的时间。因为该方法会立即返回,所以您尝试使用的 trainer 变量的值不会从回调中填充。因此,简单地将其创建为全局变量将无济于事,其值将始终为 false

    基本上,您尝试从异步 API 同步使用值。这不是一个好主意。您应该按预期异步处理 API。

    一个快速解决这个问题的方法是在回调中使用你的bool变量only的值,否则我建议你从这个@查看我的anwser的最后一部分987654321@ 我在其中解释了如何使用自定义回调来完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-24
      相关资源
      最近更新 更多