简体   繁体   中英

How to retrieve a child from Firebase when there is a unique key Kotlin

I want to retrieve specific child values like (phonenumber, firstname, familyname) from Firebase real time database but there is a unique key for each user

and this is the tree:

火力树

I've tried this:

    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()
        }
    })

and I have a simple model called User to handle the data (I know the passwords should be hashed here)

@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
        )
    }
}

but dataSnapshot.getValue<User>().!.phoneNumber will never work, since the first node retrieved in this query is the unique key

what I need is something like dataSnapshot.child("unique-key/phoneNumber").value for each child i want to use, but a way easier and more efficient than making .addChildEventListener for each node

Let's firstly give some notes one the code:

first thing you need to be aware of is here:

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

as it might be null if phoneNumber doesn't exist and will throw an error.

secondly, assuming you made some null handling it will still retrieve you empty string, because what you sent to model is just the unique key, and of course you can't handle it with this model.

The easiest way to solve this and get the children of retrieved node is by using for loop according to this solution: https://stackoverflow.com/a/38652274/10324295

you need to make for loop puts each item into an array list, try this code:

    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()
            }
        })
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()
        }
    })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM