拥有唯一密钥Kotlin时如何从Firebase检索孩子

时间:2020-04-24 19:25:04

标签: android json firebase kotlin firebase-realtime-database

我想从Firebase实时数据库中检索特定的子值,例如(电话号码,名字,姓氏) 但是每个用户都有一个唯一的密钥

这是树:

firebase tree

我已经尝试过了:

    var loginRef = rootRef.child("users").orderByChild("phoneNumber").equalTo(phone).addListenerForSingleValueEvent(
        object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            // Get data object and use the values to update the UI
            val phoneNumber = dataSnapshot.getValue<User>()!!.phoneNumber
            // ...
            Toast.makeText(applicationContext, "phone number is: $phoneNumber", Toast.LENGTH_LONG).show()

        }

        override fun onCancelled(databaseError: DatabaseError) {
            // Getting Data failed, log a message
            Log.w(TAG, "LoginData:onCancelled", databaseError.toException())
            // ...
            Toast.makeText(applicationContext, "error", Toast.LENGTH_LONG).show()
        }
    })

我有一个名为User的简单模型来处理数据(我知道密码应该在此处散列)

@IgnoreExtraProperties
data class User(
    var firstName: String? = "",
    var fatherName: String? = "",
    var familyName: String? = "",
    var phoneNumber: String? = "",
    var password: String? = ""
) {

    @Exclude
    fun toMap(): Map<String, Any?> {
        return mapOf(
            "firstName" to firstName,
            "fatherName" to fatherName,
            "familyName" to familyName,
            "phoneNumber" to phoneNumber,
            "password" to password
        )
    }
}

但是dataSnapshot.getValue<User>()!!.phoneNumber将永远无法工作,因为此查询中检索到的第一个节点是唯一键

我需要给每个想要使用的孩子使用dataSnapshot.child("unique-key/phoneNumber").value之类的东西,但是比让每个节点使用.addChildEventListener的方法更简单,更有效

2 个答案:

答案 0 :(得分:0)

首先让我们给一些注释一个代码:

您需要注意的第一件事是在这里

dataSnapshot.getValue<User>()!!.phoneNumber

如果phoneNumber不存在,则可能为null,并且会引发错误。

第二,假设您进行了空处理,它仍然会检索空字符串,因为发送给模型的只是唯一键,当然,您不能用此模型处理它。

解决此问题并获取所检索节点的子代的最简单方法是根据以下解决方案使用for循环:https://stackoverflow.com/a/38652274/10324295

您需要进行for循环以将每个项目放入数组列表,请尝试以下代码:

    val userList: MutableList<User?> = ArrayList()
    var loginRef = rootRef.child("users").orderByChild("phoneNumber").equalTo(phone).addListenerForSingleValueEvent(
        object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                userList.clear()
                for (userSnapshot in dataSnapshot.children) {
                    val user: User? = userSnapshot.getValue(User::class.java)
                    userList.add(user)

                    // Get Data object and use the values to update the UI
                    // ...
                    Toast.makeText(applicationContext, "hi: ${user!!.phoneNumber}", Toast.LENGTH_LONG).show()
                }

            }
            override fun onCancelled(databaseError: DatabaseError) {
                // Getting Data failed, log a message
                Log.w(TAG, "LoginData:onCancelled", databaseError.toException())
                // ...
                Toast.makeText(applicationContext, "error", Toast.LENGTH_LONG).show()
            }
        })

答案 1 :(得分:0)

var loginRef = rootRef.child("users").orderByChild("phoneNumber").equalTo(phone).addListenerForSingleValueEvent(
        object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            // retreive all children firstly by foreach
            dataSnapshot.children.forEach { data ->
              val userModel = data.getValue(User::class.java)
              val phoneNumber = userModel!!.phoneNumber
              Toast.makeText(applicationContext, "phone number is: $phoneNumber", 
              Toast.LENGTH_LONG).show()
            }
            // ...


        }

        override fun onCancelled(databaseError: DatabaseError) {
            // Getting Data failed, log a message
            Log.w(TAG, "LoginData:onCancelled", databaseError.toException())
            // ...
            Toast.makeText(applicationContext, "error", 
            Toast.LENGTH_LONG).show()
        }
    })
相关问题