Search code examples
androidfirebasedictionarykotlindto

How to transfer a (Mutable)Map to an Data Transfer Object Class in Kotlin?


I have a Firebase project which contains a Firestore collection of tasks that have an associated:

  • taskNumber(set as the document ID)
  • site(name)
  • status
  • location(optional)
  • description(optional)
  • notes(optional)
  • long(optional)
  • lat(optional)

There are additional fields in the Firestore that I do not wish to pass into the data transfer object like long and lat

Here is an example of the Firebase Firestore data structure: enter image description here

I use a snapshot listener to listen for changes made to the database then add the desired docments to an arrayList which I then display in a recycler view

When I try to run the code below I get Type Mismatch error @ TaskDTO(taskObj) How do I allow the TaskDTO class to accept a Map?

Here is the code:

val collRef = db.collection("centa_tasks").orderBy("scheduled_date")
        collRef.addSnapshotListener { querySnapshot, firebaseFirestoreException ->

            if (firebaseFirestoreException != null) {
                ...
            }

            ...

            for ((index,doc) in querySnapshot!!.withIndex()) {

                //Get the main values:
                var taskObj = doc.data

                //Add the task_number:
                taskObj["task_number"] = doc.id

                //Here I compare the current date to the previous date to determine if day item needs 
                //to be shown:
                if(index != 0) {
                    val ts1: Timestamp = querySnapshot.documents[index - 1]["scheduled_date"] as Timestamp
                    val ts2: Timestamp = taskObj["scheduled_date"] as Timestamp

                    taskObj["showDate"] = ts1 != ts2
                }else{
                    taskObj["showDate"] = true
                }
                val task = TaskDTO(taskObj) //This is the line of code that needs to be changed. 
                allTasks.add(task) //I add the task to an arrayList that is sent to recycler adapter. 
            }

Here is the data transfer object that contains optional parameters: TaskDTO.kt:

data class TaskDTO(var site : String,
                   var taskNumber : String,
                   var status: Int,
                   var showDate : Boolean,
                   var scheduled_date : Timestamp = Timestamp(Date(-1)), //optional
                   var description : Int = 1, //optional
                   var location : String = "No location set!", //optional
                   var notes : String = "" //optional
                  ) {

}

When I try to run the code above I get Type Mismatch error @ TaskDTO(taskObj) How do I allow the TaskDTO class to accept a Map?


Solution

  • If I understood you correctly, you are trying to initialize TaskDTO with MutableMap, but your TaskDTO class has no constructor for that case. You should create new class (I use singleton for that case), for instance TaskMapper with method fun mapTaskDTO(map: MutableMap) which creates and returns an instance of TaskDTO class based on values in instance of MutableMap. Note! This code should not be used as it is. This is just an example, which should show you the way to solve your problem.

    object TaskMapper{
        fun mapTaskDTO(map: MutableMap<String, String>): TaskDTO{
            return TaskDTO(map["site"]!!,
                map["taskNumber"]!!,
                map["status"]!!.toInt(),
                map["showDate"]!!.toBoolean())
        }
    }
    

    And then use it like here

    val task = TaskMapper.mapTaskDTO(taskObj)