无法反序列化对象。类没有定义无参构造函数。如果您使用 ProGuard,请确保这些构造函数没有被剥离

问题描述 投票:0回答:4

https://github.com/neuberfran/JThings/blob/main/app/src/main/java/neuberfran/com/jfran/model/FireFran.kt

我上面有这个 POJO,其中包含主题中提到的错误。我知道这是这里已经提到的一个错误,但是我尝试了几个类(除了这个)但我没有成功,因为我的模型/POJO 类(和代码实现)与我看到的几个不同:(每个帮助欢迎)

无法反序列化对象。类没有定义无参 构造函数。如果您使用 ProGuard,请确保这些构造函数 没有被剥离(在“值”字段中找到)

对 Garagem 文件进行更改,将价值交换为 valorb 等...

android firebase kotlin google-cloud-firestore
4个回答
18
投票

错误非常明显,您的“FireFran”类没有无参数构造函数。当您尝试从 Cloud Firestore 反序列化对象时,Android SDK 要求该类必须具有默认的无参数构造函数以及映射到每个数据库属性的设置器。

在 Kotlin 中,数据类不提供默认的无参数构造函数。因此,您需要以某种方式确保编译器所有属性都有一个初始值。您可以为所有属性提供初始值 null 或您认为更合适的任何其他值。

所以你的“FireFran”可能看起来像这样:

class FireFran(
    var alarmstate: Boolean  = false,
    var garagestate: Boolean = false,
    var id: String? = null,
    var userId: String? = null,
    var value: FireFranValue? = null //Newly added
) {
    //var value: FireFranValue = FireFranValue(false, 0)
    companion object Factory {
        fun create() :FireViewModel = FireViewModel()
        var COLLECTION = "device-configs"
        var DOCUMENT = "alarme"
        var FIELD_userId = "userId"
    }
}

现在在构造函数中添加属性,Kotlin 将自动生成一个默认的无参数构造函数。这样,Firebase Android SDK就可以使用了。它还将为每个属性生成设置器。请注意,每个属性都是 var 而不是 val,并且在“id”和“userId”的情况下提供默认的 null 值。

如果不进行此更改,您将无法使用自动反序列化。您必须从 DocumentSnapshot 对象中读取每个属性的值,并将它们全部传递给 Kotlin 的构造函数。

编辑:

  1. 在您的屏幕截图中,“value”属性位于“FireFranValue”类型的对象上,该对象只有两个属性:“brightness”和“on”。为了能够读取“value”下的数据,您的“FireFran”类应该包含一个“FireFranValue”类型的新属性。请检查班级上方。

  2. 如果您不想使用自动反序列化,您可以单独获取每个属性的值。例如,您可以使用 DocumentSnapshot 的 getString(String field) 方法获取“userId”属性的值:

     val userId = snapshot.getString("userId")
    

编辑2:

您的三个课程应如下所示:

class FireFran(
    var alarmstate: Boolean  = false,
    var garagestate: Boolean = false,
    var id: String? = null,
    var userId: String? = null,
    var owner: String? = null,
    var value: FireFranValue = FireFranValue(false),
    var valorb: FireFranValueB = FireFranValueB(openPercent = 0)
)
data class FireFranValue(
    var on: Boolean // = false
)

data class FireFranValueB(
    var openPercent: Number // = 0
)

编辑3:

class FireFran(
    var alarmstate: Boolean  = false,
    var garagestate: Boolean = false,
    var id: String? = null,
    var userId: String? = null,
    var owner: String? = null,
    var value: FireFranValue? = null,
    var valorb: FireFranValueB? = null
)
data class FireFranValue(
    var on: Boolean? = null
)

data class FireFranValueB(
    var openPercent: Number? = null
)

现在,“on”和“openPercent”将从数据库中获取值。

请检查以下类声明:


4
投票

你可以在 kotlin 中定义一个无参构造函数,如下所示:

data class SampleClass(
    val field1: String,
    val field2: String
) {
    constructor(): this("", "")
}

0
投票

第一件事:没有必要创建名为 valorb 的字段(地图类型)。它已通过 value.openPercent 解决了

由于我有两个文档(alarme 和 Garagem),我创建了两个 POJO 类(FireFran 和 FireFranB)

https://github.com/neuberfran/JThingsFinal/blob/main/app/src/main/java/neuberfran/com/jfran/model/FireFranB.kt

秘密是将 value.on 和 value.openPercent 字段视为映射(事实就是如此):


0
投票

您可以将字段设置为 null(对于 Kotlin 开发人员)

import android.os.Parcelable
import com.google.firebase.Timestamp
import kotlinx.android.parcel.Parcelize

@Parcelize
data class User(
    var id: String? = null,
    var profileImageUrl: String? = null,
    var name: String? = null,
    var position: String? = null,
    var birthPlace: String? = null,
) : Parcelable
© www.soinside.com 2019 - 2024. All rights reserved.