![](/img/trans.png)
[英]Flutter Firestore : Add a List of Data to Firestore Document
[英]Convert Firestore document to list of objects
我有这个 Firestore 文档Quiz_android
,它看起来列出了这个:
它是一个包含地图的简单数组。 现在我想将这些结果绑定到 Kotlin 中的某些对象。因此我做了以下操作:
data class QuizBody(
val questions: List<Question>
)
data class Question(
val question: String,
val answers: List<String>,
val answer: Int
)
Quizbody
只是列表中测验的所有问题,在该列表中,我有Question
类,它应该能够存储通话中的所有数据。
但是我如何将调用的结果绑定到这些对象呢?
suspend fun getQuestions(quizToGet: String) {
try {
//firestore has support for coroutines via the extra dependency we've added :)
withTimeout(5_000) {
firestore.collection("Quizzes").document(quizToGet).get()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
val result = task.result
if (result.exists()) {
val myObject = result.toObject(QuizBody::class.java)
println(myObject)
}
}
}
}
} catch (e: Exception) {
throw QuizRetrievalError("Retrieving a specific quiz was unsuccessful")
}
}
我做了这个,但这不起作用。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.hva.madlevel7task2, PID: 3995
java.lang.RuntimeException: Could not deserialize object. Class com.hva.madlevel7task2.model.QuizBody does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped
编辑:
我更新了数据class:
data class QuizBody(
var questions: List<Question>? = null
)
data class Question(
var question: String? = null,
var answers: List<String>? = null,
var answer: Int? = null
)
suspend fun getQuestions(quizToGet: String)
它仍然是一样的,现在我在控制台中得到了这个:
I/QuizViewModel: function: getListQuestions
W/Firestore: (24.1.1) [CustomClassMapper]: No setter/field for Questions found on class com.hva.madlevel7task2.model.QuizBody (fields/setters are case sensitive!)
I/System.out: QuizBody(questions=null)
出现以下错误:
java.lang.RuntimeException:无法反序列化 object。Class com.hva.madlevel7task2.model.QuizBody 未定义无参数构造函数。
在我看来是非常直截了当的。 您的 class “QuizBody”没有无参数构造函数。 当您尝试反序列化来自 Firestore 数据库的 object 时,Android SDK 要求 class 应强制具有默认的无参数构造函数。
在 Kotlin 中,如果 class 的所有属性都使用val
声明,则数据类不提供默认的无参数构造函数。 对于此类属性,Kotlin 要求在构造函数中指定它们的值,因为它们以后不可能更改。 所以这是必需的,因为我们需要确保编译器所有的属性都有一个初始值。 您可以为所有属性提供初始值 null 或您认为更合适的任何其他值。 所以你的类应该是这样的:
data class QuizBody(
var questions: List<Question>? = null
👆 👆
)
data class Question(
var question: String? = null,
var answers: List<String>? = null,
var answer: Int? = null
)
现在在构造函数中添加属性,Kotlin会自动生成一个默认的无参构造函数。 这样,Firebase Android SDK 将能够用于为每个属性生成 setter。 如果不进行此更改,您将无法使用自动反序列化。 您必须从DocumentSnapshot object 中读取每个属性的值,并将它们全部传递给 Kotlin 的构造函数。
编辑:
if (task.isSuccessful) {
val document = task.result
if (document.exists()) {
val myObject = document.toObject(QuizBody::class.java)
println(myObject)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.