无法反序列化对象。类未定义无参数构造函数。如果您使用ProGuard,请确保这些构造函数未被剥离
https://github.com/neuberfran/JThings/blob/main/app/src/main/java/neuberfran/com/jfran/model/FireFran.kt
我有这个 POJO 上面提到了主题中提到的错误。我知道这是这里已经提到的错误,但是我尝试了几个类(除了这个类)但我没有成功,因为我的模型/POJO 类(和代码实现)与我看到的几个不同:(每个帮助欢迎)
无法反序列化对象。类没有定义无参数构造函数。如果您使用 ProGuard,请确保这些构造函数没有被剥离(在字段“值”中找到)
对garagem 文件进行了更改,用valorb 交换了价值,等等......
回答
错误很明显,您的类“FireFran”没有无参数构造函数。当您尝试从 Cloud Firestore 反序列化对象时,Android SDK 要求该类必须具有默认的无参数构造函数以及映射到每个数据库属性的 setter。
在 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”的情况下提供默认空值。
如果不进行此更改,您将无法使用自动反序列化。您必须从DocumentSnapshot对象中读取每个属性的值,并将它们全部传递给 Kotlin 的构造函数。
编辑:
-
在您的屏幕截图中,“value”属性位于“FireFranValue”类型的对象上,该对象只有“brightness”和“on”两个属性。为了能够读取“value”下的数据,您的“FireFran”类应该包含一个“FireFranValue”类型的新属性。请检查上面的类。
-
如果不想使用自动反序列化,可以单独获取每个属性的值。例如,您可以使用 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”将从数据库中获取值。
请检查以下类声明:
- I'm not sure how are these changes related to your initial question, but the entire idea is to have the no-argument constructor for class and inner classes. Keep me posted.
- In see. Please check my last edit (Edit3). Does it work now?
- Yes, both FireFran and FireFranValue must have the no-argument constructor. For the `value` you should also add another property of type FireFranValue in the class. Does it work now?
- Please check my updated answer. Is it clear now?
- Yes, in that image I see a variable naming issue. So the fields should remain "value", as it is in the database, and change the second one. Or simply comment line 14. Does it work now?
- Creating a new object of your "FireFranValue" class doesn't help there. Besides that, all objects should have **different names**. Give it try again.
- Yes, all objects should have different names. There is no way you can have two fields with the same name. Tou added a new class in your code "FireFranValueB". That class and the corresponding property "valorb" (from the database) will not solve your actual problem. If you need a new property called "valorb", you should map that property to an object of type "FireFranValueB". But you still need to have different names in your class, right?
- Please check my updated answer. Does it work now?
- With the new changes, can you get the desired data? The companion object can be placed in the class.
- Good to hear that you made it work 😉
- What exactly is left now?
- I might take a look at this **[answer](https://stackoverflow.com/questions/60719791/firebase-firestore-variable-name-changed/60719948#60719948)**, does it help?
- Is "openPercent" not a number? Besides that, all classes should be added to the ProGuard rules, including the sub-classes.
- @NEUBERSOUSA Your new class looks good to me. What's the problem now?