Home > Back-end >  DIsplay Data from Firestore on a RecyclerView using Kotlin
DIsplay Data from Firestore on a RecyclerView using Kotlin

Time:05-30

Im trying to get the data from a collection into an ArrayList so i can further display it on a RecycleView.

The Data class is the following:

data class Proyecto(
    val alcances :String,
    val alumnos :HashMap<String, Any>,
    val areasConoc :String,
    val asignaturas :String,
    val cliente :String,
    val colaboradores :String,
    val compDes :String,
    val compPrev :String,
    val coordinador: String,
    val departamentos  :String,
    val impacto :String,
    val institucion :String,
    val justificacion :String,
    val limityrest :String,
    val materiaEje :String,
    val periodo : HashMap<String, Any>,
    val plan :String,
    val planteamiento :String,
    val profeResp :String,
    val tipoejec :String,
    val tituloproyecto :String

)

I only need to get the fields tituloproyecto, coordinador and cliente into the recyclerview, so this is my recyclerview adapter:

class MyAdapter (private val projectList : ArrayList): RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    val itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item,parent,false)

    return MyViewHolder(itemView)
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    val proyecto : Proyecto = projectList[position]

    holder.tituloproyecto.text = proyecto.tituloproyecto
    holder.coordinador.text = proyecto.coordinador
    holder.cliente.text = proyecto.cliente
}

override fun getItemCount(): Int {

   return  projectList.size
}

public class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
    val tituloproyecto : TextView = itemView.findViewById(R.id.tv_titulo_rv)
    val coordinador: TextView = itemView.findViewById(R.id.tv_coordinador_rv)
    val cliente: TextView = itemView.findViewById(R.id.tv_cliente_rv)
}

}

And this is the code of the Activity that will display the recyclerview: class ProyectosAlumnoActivity : AppCompatActivity() {

private lateinit var recyclerView: RecyclerView
private lateinit var projectArrayList: ArrayList<Proyecto>
private lateinit var myAdapter: MyAdapter
private lateinit var db : FirebaseFirestore

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_proyectos_alumno)
    supportActionBar?.setTitle("Proyectos de Lorenzo")

    recyclerView = findViewById(R.id.recyclerView_al)
    recyclerView.layoutManager = LinearLayoutManager (this)
    recyclerView.setHasFixedSize(true)

    projectArrayList = arrayListOf()

    myAdapter = MyAdapter(projectArrayList)
    recyclerView.adapter = myAdapter

    EventChangeListener()
}

private fun EventChangeListener() {
    db = FirebaseFirestore.getInstance()

// db.collection("Proyecto").get().addOnSuccessListener { }

    db.collection("Proyecto")
        .addSnapshotListener(object : EventListener<QuerySnapshot>{
            override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
                if (error != null)
                {
                    Log.e("Firestore error", error.message.toString())
                    return
                }

                for (dc: DocumentChange in value?.documentChanges!!){
                    if (dc.type == DocumentChange.Type.ADDED){
                        projectArrayList.add(dc.document.toObject(Proyecto::class.java))
                    }
                }
                myAdapter.notifyDataSetChanged()

            }
    })


}

I got the following error message:

2022-05-29 18:30:38.363 6252-6252/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.firebasecrudapplication, PID: 6252 java.lang.RuntimeException: Could not deserialize object. Class com.example.firebasecrudapplication.models.Proyecto does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped at com.google.firebase.firestore.util.CustomClassMapper.deserializeError(CustomClassMapper.java:568) at com.google.firebase.firestore.util.CustomClassMapper.access$200(CustomClassMapper.java:57) at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:754) at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:746) at com.google.firebase.firestore.util.CustomClassMapper.convertBean(CustomClassMapper.java:547) at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(CustomClassMapper.java:258) at com.google.firebase.firestore.util.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:103) at com.google.firebase.firestore.DocumentSnapshot.toObject(DocumentSnapshot.java:183) at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(QueryDocumentSnapshot.java:116) at com.google.firebase.firestore.DocumentSnapshot.toObject(DocumentSnapshot.java:161) at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(QueryDocumentSnapshot.java:97) at com.example.firebasecrudapplication.ProyectosAlumnoActivity$EvenChangeListener$1.onEvent(ProyectosAlumnoActivity.kt:55) at com.example.firebasecrudapplication.ProyectosAlumnoActivity$EvenChangeListener$1.onEvent(ProyectosAlumnoActivity.kt:45) at com.google.firebase.firestore.Query.lambda$addSnapshotListenerInternal$2$com-google-firebase-firestore-Query(Query.java:1205) at com.google.firebase.firestore.Query$$ExternalSyntheticLambda2.onEvent(Unknown Source:6) at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0$com-google-firebase-firestore-core-AsyncEventListener(AsyncEventListener.java:42) at com.google.firebase.firestore.core.AsyncEventListener$$ExternalSyntheticLambda0.run(Unknown Source:6) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7842) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

leading me to believe that the issue here is the hashmap fields not being properly parsed into the arraylist.

Any ideas of what i can do to fix this?

CodePudding user response:

You need to provide default values to your model fields. Firestore will assign that default value to the field in case that particular field is missing from the document snapshot.

data class Proyecto(
    val alcances: String = "",
    val alumnos: HashMap<String, Any> = hashMapOf(),
    val areasConoc: String = "",
    val asignaturas: String = "",
    val cliente: String = "",
    val colaboradores: String = "",
    val compDes: String = "",
    val compPrev: String = "",
    val coordinador: String = "",
    val departamentos: String = "",
    val impacto: String = "",
    val institucion: String = "",
    val justificacion: String = "",
    val limityrest: String = "",
    val materiaEje: String = "",
    val periodo: HashMap<String, Any> = hashMapOf(),
    val plan: String = "",
    val planteamiento: String = "",
    val profeResp: String = "",
    val tipoejec: String = "",
    val tituloproyecto: String = ""
)

Also, it is recommended to use Kotlin's immutable Map instead of Java's HashMap.

CodePudding user response:

I think you are missing a ; bro, i hope to help you :)

  • Related