In an Android Kotlin app connected to a firestore backend,
I have the following data class:
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.util.Date
@Serializable
data class Task(
@Serializable(with = TaskCategorySerializer::class)
val category: TaskCategory = TaskCategory.OTHER,
@Serializable(with = Serializers.Companion.DateSerializer::class)
val due_date: Date? = null,
)
object TaskCategorySerializer : KSerializer<TaskCategory> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("TaskCategory",
PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: TaskCategory) {
encoder.encodeString(value.name)
}
override fun deserialize(decoder: Decoder): TaskCategory {
return try {
val value = decoder.decodeString()
if (value.isEmpty()) TaskCategory.OTHER else TaskCategory.valueOf(value)
} catch (e: RuntimeException) {
TaskCategory.OTHER
}
}
}
And I am fetching the tasks using the following code:
fun fetchTasks(boatId: String) {
listenerRegistration = db.collection(Firestore.COLLECTION_TASKS)
.addSnapshotListener { snapshot, exception ->
if (exception != null) {
return@addSnapshotListener
}
if (snapshot != null && !snapshot.isEmpty) {
val tasks = snapshot.documents.map { task ->
task.toObject(Task::class.java)!!
}
_tasks.value = tasks
} else {
Log.d(TAG, "Current data: null")
}
}
}
When the DB contains values which are missing from the TaskCategory enum I am getting the following error in the logcat:
java.lang.RuntimeException: Could not deserialize object. Could not find enum value of
TaskCategory for value “” (found in field ‘category’)
I was expecting the custom deserializer to catch that exception and return a default value.
I do not understand why the custom deserializer is not being used. Is there another way to define a custom deserializer for firestore?