将 Firestore 文档转换为对象列表

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
)

A Quizbody 只是列表中测验的所有问题,在该列表中,我有 classes of 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: Could not deserialize object. Class com.hva.madlevel7task2.model.QuizBody does not define a no-argument constructor.

在我看来非常直截了当。您的 class “QuizBody” 而不是 具有 no-argument 构造函数。当您尝试反序列化来自 Firestore 数据库的对象时,Android SDK 要求 class 必须具有默认的 no-argument 构造函数。

在 Kotlin 中,如果 class 的所有属性都使用 val 声明,则数据 classes 不提供默认的 no-arg 构造函数。对于此类属性,Kotlin 要求在构造函数中指定它们的值,因为它们以后不可能更改。所以这是必需的,因为我们需要确保编译器所有的属性都有一个初始值。您可以为所有属性提供初始值 null 或您认为更合适的任何其他值。所以你的 classes 应该是这样的:

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 会自动生成一个默认的 no-argument 构造函数。这样,Firebase Android SDK 将能够用于为每个 属性 生成设置器。如果不进行此更改,您将无法使用自动反序列化。您必须从 DocumentSnapshot 对象中读取每个 属性 的值,并将它们全部传递给 Kotlin 的构造函数。

编辑:

if (task.isSuccessful) {
    val document = task.result
    if (document.exists()) {
        val myObject = document.toObject(QuizBody::class.java)
        println(myObject)
    }
}