Hon Ey Mon Ey
Hon Ey Mon Ey

Reputation: 87

How to fix java.lang.ClassCastException: java.lang.Class cannot be cast to java.util.Map

I'm using this code to detect if a value has changed on my firebase real-time database, but i got this error:

java.lang.ClassCastException: java.lang.Class cannot be cast to java.util.Map

    val ref = FirebaseDatabase.getInstance().reference.child("Users")
    ref.addChildEventListener(object : ChildEventListener {
        override fun onCancelled(p0: DatabaseError) {
            TODO("Not yet implemented")
        }

        override fun onChildMoved(p0: DataSnapshot, p1: String?) {
            TODO("Not yet implemented")
        }

        @SuppressLint("LongLogTag")
        override fun onChildChanged(dataSnapshot: DataSnapshot, p1: String?) {
            collectData(dataSnapshot.value as Map<String?, Any?>?)
        }

        override fun onChildAdded(dataSnapshot: DataSnapshot, s: String?) {
        }

        override fun onChildRemoved(p0: DataSnapshot) {
            TODO("Not yet implemented")
        }
    })

the collectData function

fun collectData(docs: Map<String?, Any?>?){
    doctorsArrayList.clear()
    if (docs != null) {
        for ((_, value) in docs) {
            //Get user map
            val singleUser =
                value as Map<*, *>
            //Get phone field and append to list
                doctorsArrayList.add(Doctors(
                    singleUser["name"] as String?,
                    "","",
                    singleUser["lastDate"] as String?,
                    singleUser["phoneNumber"] as String? ,
                    singleUser["muid"] as String?,
                    singleUser["speciality"] as String?,
                    singleUser["status"] as Boolean?)
                )
        }
        val myrv = findViewById<RecyclerView>(R.id.docRV)
        val myAdapter = DoctorsRV(this, doctorsArrayList)
        myrv.layoutManager = GridLayoutManager(this, 1)
        myrv.adapter = myAdapter
    }
}

STACK TRACE

> java.lang.ClassCastException: java.lang.String cannot be cast to
> java.util.Map
>         at packageName.doctor.DoctorsList.collectData(DoctorsList.kt:39)
>         at packageName.doctor.DoctorsList$onCreate$2.onChildChanged(DoctorsList.kt:87)
>         at com.google.firebase.database.core.ChildEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.3.0:82)
>         at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.3.0:63)
>         at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.3.0:55)
>         at android.os.Handler.handleCallback(Handler.java:907)
>         at android.os.Handler.dispatchMessage(Handler.java:99)
>         at android.os.Looper.loop(Looper.java:223)
>         at android.app.ActivityThread.main(ActivityThread.java:7478)
>         at java.lang.reflect.Method.invoke(Native Method)
>         at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
>         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)

Help me please, thank you

Upvotes: 0

Views: 2361

Answers (1)

goedi
goedi

Reputation: 2123

This exception can happen in two places:

  1. dataSnapshot.value is different of null and isn't a Map.
  2. value as Map<*, *> isn't a Map.

Before trying to convert a value to a Map you need to check if it is a Map and if not, handle this case appropriately.

EDIT:

You can use the as? operator which returns null on a failure to cast: https://kotlinlang.org/docs/reference/typecasts.html?&_ga=2.160730555.728369396.1590324399-1451069023.1560810152#safe-nullable-cast-operator

You're already checking when the first cast results in null in if (docs != null). Now you need to do the same for the second case, that is, execute doctorsArrayList.add only if singleUser is different of null.

Upvotes: 2

Related Questions