有没有办法在 DocumentSnapshot.toObject() 中添加类型转换?

问题描述

我想让我的 Kotiln 应用与 Firestore 组件的耦合更少。

我有一个曾经看起来像这样的模型:

data class MyObjectModel(
    @DocumentId val id: String = "",var title: String = "",var media: List<String> = listOf()
)

因为它在应用程序中被广泛使用,所以它与 Firestore 非常耦合(例如,媒体列表应该是 url,我使用字符串只是因为 DocumentSnapshot.toObject() 有趣的限制)。我读到 Kotlin 数据类在继承方面很成问题,所以我想制作一个这样的接口:

interface MyObject{
    val id: String
    var title: String
    val media: MutableList<Uri>
}

并在整个应用中使用它。

为了从 Firestore 获取对象,我想构建一个实现该接口的 POJO,如下所示:

data class MyObjectPojo(
    @DocumentId override val id: String,override var title: String,override val media: MutableList<Uri>
) : MyObject {
    constructor(id: String,title: String,media: List<String>) : 
            this(id,title,media.map { Uri.parse(it) } as MutableList<Uri>)
}

我发现这是不可能的,原因有两个:

  1. 第二个构造函数给出错误:“平台声明冲突:以下声明具有相同的 JVM 签名 ( (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V):... "
  2. DocumentSnapshot.toObject() 函数仅调用主构造函数,这在我的情况下不起作用(因为它不支持将字符串自动解析为 Uris)

此外,随着我​​的对象将增长到具有更多字段,这变得不再需要很多样板...

为此我想到了一个解决方案:删除第二个构造函数并将主要构造函数的最后一个参数从override val media: MutableList<Uri> 更改为val mediaStringList: MutableList<String>。我可以在类主体中执行以下操作之一:

    // Solution 1
    override val media: MutableList<Uri>
        get() = mediaStringList.map { Uri.parse(it) } as MutableList<Uri>

    // Solution 2
    override val media = mediaStringList.map { Uri.parse(it) } as MutableList<Uri>

两者都很丑,因为第一个意味着每次 get 调用都执行列表映射操作,第二个意味着将列表保存两次。如果我可以向构造函数添加一个主体,我将能够从 val 参数中删除 mediaStringList,但我想根据主构造函数的定义,这是不可能的...

我现在看到的唯一方法是实现我自己的 toMyObject() 函数,但这也意味着为 set() 函数实现另一种方式 - 我真的很想避免这样做对于我拥有的每个对象。还有其他方法可以解决这个问题吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)