【问题标题】:Firebase Cloud Firestore: Sealed classes in custom objects in Kotlin AndroidFirebase Cloud Firestore:Kotlin Android 中自定义对象中的密封类
【发布时间】:2020-04-26 21:23:42
【问题描述】:

我正在使用

implementation 'com.google.firebase:firebase-firestore:21.3.1'

用于在 1.3.50 版中使用 Kotlin 测试 Firestore-Database SDK。

对于读/写测试,我创建了一个简单的数据类:

data class Location(
    val uuid: String? = null,
    val name: String? = null
)

正如预期的那样运行良好且流畅。

但是用 Kotlin 的密封类更深入地扩展数据类会导致序列化问题:

data class Location(
    val uuid: String? = null,
    val name: String? = null,
    val locationProperty: LocationProperty? = null
)

sealed class LocationProperty {

    data class TextProperty(
        val text: String? = null
    ) : LocationProperty()
}

虽然写入数据库仍然可以正常工作,但应用程序在序列化结果时会引发异常:

document.toObject(Location::class.java)
java.lang.RuntimeException: No properties to serialize found
on class com.abc.def.LocationProperty

在 Firestore 前端,我看到我的密封类在 NoSQL 数据库中保存为 Map,收到的 DocumentSnapshot 的原始数据如下所示

(locationProperty =>ArraySortedMap{(text=>My entered text)}

所以这可能会导致错误。

有什么办法可以解决这个问题,如果可能的话,可以通过在向 Firestore 读取或写入数据时提供自定义序列化程序吗?

【问题讨论】:

    标签: android firebase kotlin google-cloud-firestore


    【解决方案1】:

    您将无法使用带有toObject() 的密封类。这是因为密封类本身没有足够的信息来了解您真正想要读取和写入的属性。只有作为密封类的子类的具体类才能工作,因为反射可用于在运行时确定它们的所有属性。

    Firestore 的类反射对象序列化根本不适合这个特定的用例。您应该提供您的数据以另存为Map<String, *>。阅读文档时,数据也会以同样的方式显示。那是因为 Firestore 在内部将您的对象转换为 Map 或从 Map 转换。这将涉及编写一堆代码来使用对象的属性读取和写入该 Map 的条目,这实际上很正常。

    Firestore SDK 目前没有任何“序列化程序”插件的概念,该插件可让您拦截正在序列化的对象以执行转换。在写入文档之前必须序列化为 Map,在读取文档时必须从 Map 反序列化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-10
      • 2021-03-06
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      • 2019-07-28
      • 1970-01-01
      相关资源
      最近更新 更多