【问题标题】:Union classes or class erasure for Firestore desereliazation in KotlinKotlin 中 Firestore 解散的联合类或类擦除
【发布时间】:2019-08-31 07:09:06
【问题描述】:

我有一个 Firestore 集合,其中包含没有公共键或值的不同数据对象。 在 Kotlin 中,这表示为类似

sealed class Task()
data class WorkTask(val id: String): Task()
data class ReductionTask(val time: Date): Task()

我想以如下方式反序列化 Firestore 集合中的数据:

val tasks = result.toObjects(Task::class.java)
val workTasks = result.filterInstance(WorkTask::class.java)
val reductionTasks= result.filterInstance(ReductionTask::class.java)

总之,我想从 Firestore WorkTask | ReductionTask | OtherTask 检索一个联合,我可以将它保存在一个列表中,然后按实例进行过滤或模式匹配。

编辑: 目前,我的解决方法是使用 1 个通用键 (type) 来保存对象的类型:

inline fun <reifed T: Any> QuerySnapshot.deserializeByType(
    crossinline selector: (type:String) -> Class<out T>
): List<T> {

   return this.documents.map({ document ->
      val type = firestoreDoc.getString("type")
      document.toObject(selector(type))
   })

}

querySnapshot.deserializeByType<Task> { type ->
   when (type) {
      "WORK" -> WorkTask::class.java
      "REDUCE" -> ReductionTask::class.java
      ...
   }
}


理论上,我可以只提供一个类列表并让它尝试/捕获来反序列化。但这似乎很糟糕。

【问题讨论】:

    标签: kotlin google-cloud-firestore


    【解决方案1】:

    由于 Firestore SDK 是用 Java 实现的,它对 Kotlin 密封类一无所知。它完全基于对 JavaBean 样式 POJO 对象的理解,这些对象使用类上的 getter 和 setter 方法的名称约定。 toObject() 只是将 Firestore 文档字段的名称映射到提供的类实例上的 getter 和 setter(通过反射获得)。就是这样。

    您的解决方法(或它的一些变体)是目前唯一可行的选择,因为您的代码需要判断相关文档实际表示的是哪个实际类。 Firestore SDK 确实无法知道文档应该填充哪个类 - 您必须告诉它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      • 2019-08-22
      相关资源
      最近更新 更多