Reputation: 87
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
Reputation: 2123
This exception can happen in two places:
dataSnapshot.value
is different of null and isn't a Map
.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