繁体   English   中英

将 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
)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM