GitLiveApp / firebase-kotlin-sdk

A Kotlin-first SDK for Firebase
https://gitliveapp.github.io/firebase-kotlin-sdk/
Apache License 2.0
1.17k stars 156 forks source link

Polymorphic Deserialization #643

Open richardortiz84 opened 1 month ago

richardortiz84 commented 1 month ago

I am attempting to setup a polymorphic object that will be contained within another object. Serialization and saving to the database is working as intended, but fetching and deserializing from the server is throwing a Serialization Exception.

The object is setup as follows:

@Serializable
data class Job(
    val appointments: List<Appointment>,
)

@Serializable
@FirebaseClassDiscriminator("Type")
sealed class Appointment {
    @Serializable
    @SerialName("Sales")
    data class Sales(
    ) : Appointment()

    @Serializable
    @SerialName("Service")
    data class Service(
    ) : Appointment()
}
                jobs = snapshot.documents.mapNotNull { document ->
                    try {
                        document.data<Job>()
                    } catch (ex: SerializationException) {
                        null
                    } catch (ex: NullPointerException) {
                        null
                    }
                }
kotlinx.serialization.SerializationException: Exception during decoding data.Job appointments
0 = {StackTraceElement@37373} "dev.gitlive.firebase.internal.FirebaseCompositeDecoder.decodeElement(decoders.kt:169)"
1 = {StackTraceElement@37374} "dev.gitlive.firebase.internal.FirebaseCompositeDecoder.decodeSerializableElement(decoders.kt:113)"
2 = {StackTraceElement@37375} "data.Job$$serializer.deserialize(Job.kt:6)"
3 = {StackTraceElement@37376} "data.Job$$serializer.deserialize(Job.kt:6)"
4 = {StackTraceElement@37377} "dev.gitlive.firebase.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:43)"
5 = {StackTraceElement@37378} "dev.gitlive.firebase.internal.FirebaseDecoder.decodeSerializableValue(decoders.kt:73)"
6 = {StackTraceElement@37379} "dev.gitlive.firebase.internal.DecodersKt.decode(decoders.kt:34)"
7 = {StackTraceElement@37380} "domain.JobsRepositoryImpl$getJobs$2$1.emit(JobsRepository.kt:70)"
8 = {StackTraceElement@37381} "domain.JobsRepositoryImpl$getJobs$2$1.emit(JobsRepository.kt:25)"
9 = {StackTraceElement@37382} "kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Channels.kt:33)"
10 = {StackTraceElement@37383} "kotlinx.coroutines.flow.FlowKt__ChannelsKt.access$emitAllImpl$FlowKt__ChannelsKt(Channels.kt:1)"
11 = {StackTraceElement@37384} "kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend(Unknown Source:14)"
12 = {StackTraceElement@37385} "kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)"
13 = {StackTraceElement@37386} "kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:221)"
14 = {StackTraceElement@37387} "kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:177)"
15 = {StackTraceElement@37388} "kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:149)"
16 = {StackTraceElement@37389} "kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:470)"
17 = {StackTraceElement@37390} "kotlinx.coroutines.CancellableContinuationImpl.completeResume(CancellableContinuationImpl.kt:591)"
18 = {StackTraceElement@37391} "kotlinx.coroutines.channels.BufferedChannelKt.tryResume0(BufferedChannel.kt:2957)"
19 = {StackTraceElement@37392} "kotlinx.coroutines.channels.BufferedChannelKt.access$tryResume0(BufferedChannel.kt:1)"
20 = {StackTraceElement@37393} "kotlinx.coroutines.channels.BufferedChannel$BufferedChannelIterator.tryResumeHasNext(BufferedChannel.kt:1719)"
21 = {StackTraceElement@37394} "kotlinx.coroutines.channels.BufferedChannel.tryResumeReceiver(BufferedChannel.kt:662)"
22 = {StackTraceElement@37395} "kotlinx.coroutines.channels.BufferedChannel.updateCellSend(BufferedChannel.kt:478)"
23 = {StackTraceElement@37396} "kotlinx.coroutines.channels.BufferedChannel.access$updateCellSend(BufferedChannel.kt:33)"
24 = {StackTraceElement@37397} "kotlinx.coroutines.channels.BufferedChannel.trySend-JP2dKIU(BufferedChannel.kt:3360)"
25 = {StackTraceElement@37398} "kotlinx.coroutines.channels.ChannelCoroutine.trySend-JP2dKIU(Unknown Source:2)"
26 = {StackTraceElement@37399} "dev.gitlive.firebase.firestore.internal.NativeQueryWrapper$snapshots$1.invokeSuspend$lambda$2(NativeQueryWrapper.kt:25)"
27 = {StackTraceElement@37400} "dev.gitlive.firebase.firestore.internal.NativeQueryWrapper$snapshots$1.$r8$lambda$_cT1NmzN7ybap4eVK6bJzInNDms(Unknown Source:0)"
28 = {StackTraceElement@37401} "dev.gitlive.firebase.firestore.internal.NativeQueryWrapper$snapshots$1$$ExternalSyntheticLambda0.onEvent(D8$$SyntheticClass:0)"
29 = {StackTraceElement@37402} "com.google.firebase.firestore.Query.lambda$addSnapshotListenerInternal$3$com-google-firebase-firestore-Query(Query.java:1176)"
30 = {StackTraceElement@37403} "com.google.firebase.firestore.Query$$ExternalSyntheticLambda0.onEvent(D8$$SyntheticClass:0)"
31 = {StackTraceElement@37404} "com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0$com-google-firebase-firestore-core-AsyncEventListener(AsyncEventListener.java:42)"
32 = {StackTraceElement@37405} "com.google.firebase.firestore.core.AsyncEventListener$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)"
33 = {StackTraceElement@37406} "android.os.Handler.handleCallback(Handler.java:959)"
34 = {StackTraceElement@37407} "android.os.Handler.dispatchMessage(Handler.java:100)"
35 = {StackTraceElement@37408} "android.os.Looper.loopOnce(Looper.java:232)"
36 = {StackTraceElement@37409} "android.os.Looper.loop(Looper.java:317)"
37 = {StackTraceElement@37410} "android.app.ActivityThread.main(ActivityThread.java:8592)"
38 = {StackTraceElement@37411} "java.lang.reflect.Method.invoke(Native Method)"
39 = {StackTraceElement@37412} "com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)"
40 = {StackTraceElement@37413} "com.android.internal.os.ZygoteInit.main(ZygoteInit.java:878)"
richardortiz84 commented 1 month ago

Here is what I see on the server.

image