firebase-kotlin-sdk
firebase-kotlin-sdk copied to clipboard
ClassCastException when deserialising sealed class from Firestore in KotlinJS
I'm trying to serialise/deserialise the following model into Firestore on KotlinJS with nodeJs() target, which is correctly written to Firestore, along with its generated type.
@Serializable
data class ApiSearchSession(
val id: String,
val state: ApiState
)
@Serializable
sealed class ApiState {
@Serializable
object Searching : ApiState()
}
I'm writing this to Firestore like this
val document = firebaseFirestore
.collection("COLLECTION")
.document(searchSession.id)
document.set(
data = searchSession.toApiSearchSession(),
encodeDefaults = true
)
However, when deserialising I'm getting a ClassCastException. My deserialisation code is
val document = firebaseFirestore
.collection("searchSession")
.document(id)
.get()
return if (document.exists) {
val apiSearchSession: ApiSearchSession = document.data()
apiSearchSession.toSearchSession()
} else {
null
}
Am I missing something? I've tried serialising the above to/from Strings with kotlinx.serialisation and it works as it should which lead me to think it's an SDK issue here. I'm on version 1.6.2 of the SDK.
Thanks in advance! 🙏
Also, worth noting that normal object serialisation works. I'm seeing the issue with sealed classes only.
As a workaround I've added a custom serializer which converts to/from String.
private object SessionStateSerializer : KSerializer<ApiSearchSession.State> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(
serialName = "ApiSearchSession.State",
kind = PrimitiveKind.STRING
)
override fun deserialize(decoder: Decoder): ApiSearchSession.State {
return Json.decodeFromString(decoder.decodeString())
}
override fun serialize(
encoder: Encoder,
value: ApiSearchSession.State
) {
encoder.encodeString(Json.encodeToString(value))
}
}
and am using it on the property directly like
@Serializable(with = SessionStateSerializer::class)
val state: State