【问题标题】:How to retrieve a child from Firebase when there is a unique key Kotlin当有唯一键 Kotlin 时如何从 Firebase 检索孩子
【发布时间】:2020-08-08 11:24:20
【问题描述】:

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

这就是树:

我试过了:

    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&lt;User&gt;()!!.phoneNumber 永远不会起作用,因为在此查询中检索到的第一个节点是唯一键

我需要为我想要使用的每个孩子提供类似dataSnapshot.child("unique-key/phoneNumber").value 的东西,但比为每个节点创建.addChildEventListener 更容易和更有效

【问题讨论】:

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


    【解决方案1】:

    让我们先对代码做一些注释:

    您需要注意的第一件事是:

    dataSnapshot.getValue&lt;User&gt;()!!.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()
                }
            })
    

    【讨论】:

      【解决方案2】:
      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()
              }
          })
      

      【讨论】:

        猜你喜欢
        • 2020-04-10
        • 1970-01-01
        • 2017-01-28
        • 2021-03-11
        • 1970-01-01
        • 1970-01-01
        • 2017-09-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多