首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法反序列化对象。不能将java.lang.String类型的对象转换为com.example.quiz.models.Question类型(在字段‘questions.title’中找到)

无法反序列化对象。不能将java.lang.String类型的对象转换为com.example.quiz.models.Question类型(在字段‘questions.title’中找到)
EN

Stack Overflow用户
提问于 2022-04-24 08:07:33
回答 1查看 509关注 0票数 0

我正在尝试从Firestore中获取数据。但是这个错误发生了:

java.lang.RuntimeException:无法反序列化对象。无法将java.lang.String类型的对象转换为com.example.quiz.models.Question类型(在“questions.title”字段中找到)

错误出现在setUpFirestore()中,因为行: Log.d("DATA",value.toObjects(Quiz::class.java).toString()) {as per logcat error}

我的MainActivity:

代码语言:javascript
复制
    package com.example.quiz.activities

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.recyclerview.widget.GridLayoutManager
import com.example.quiz.R
import com.example.quiz.adapters.QuizAdapter
import com.example.quiz.databinding.ActivityMainBinding
import com.example.quiz.models.Quiz
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.FirebaseFirestore
import java.text.SimpleDateFormat
import java.util.*

class MainActivity() : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
    lateinit var adapter: QuizAdapter
    private var quizList = mutableListOf<Quiz>()
    lateinit var firestore : FirebaseFirestore

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setUpViews()
    }

    fun setUpViews(){
        setUpFirestore()
        setUpDrawerLayout()
        setUpRecyclerView()
        setUpDatePicker()
    }

    private fun setUpDatePicker() {
        val btnDatePicker = binding.btnDatePicker
        btnDatePicker.setOnClickListener{
            val datePicker = MaterialDatePicker.Builder.datePicker().build()
            datePicker.show(supportFragmentManager,"DatePicker")
            datePicker.addOnPositiveButtonClickListener {
                Log.d("DATEPICKER",datePicker.headerText)
                val dateFormatter =  SimpleDateFormat("dd-mm-yyyy")
                val date = dateFormatter.format(Date(it))
                val intent = Intent(this,QuestionActivity::class.java)
                intent.putExtra("DATE",date)
                startActivity(intent)
            }
            datePicker.addOnNegativeButtonClickListener {
                Log.d("DATEPICKER",datePicker.headerText)
            }
            datePicker.addOnCancelListener {
                Log.d("DATEPICKER","Date Picker was cancelled")
            }
        }
    }

    private fun setUpFirestore() {
        firestore = FirebaseFirestore.getInstance()
        val collectionReference = firestore.collection("quizzes")
        collectionReference.addSnapshotListener{ value,error ->
            if(value == null || error != null){
                Toast.makeText(this,"Error fetching data",Toast.LENGTH_SHORT).show()
                return@addSnapshotListener
            }
            Log.d("DATA", value.toObjects(Quiz::class.java).toString())
            quizList.clear()
            quizList.addAll(value.toObjects(Quiz::class.java))
            adapter.notifyDataSetChanged()
        }
    }

    private fun setUpRecyclerView(){
        val quizRecyclerView = binding.quizRecyclerView
        adapter = QuizAdapter(this,quizList)
        quizRecyclerView.layoutManager = GridLayoutManager(this,2)
        quizRecyclerView.adapter = adapter
    }

    fun setUpDrawerLayout(){
        val appBar = binding.appBar
        val mainDrawer = binding.mainDrawer
        val navigationView = binding.navigationView
        setSupportActionBar(appBar)
        actionBarDrawerToggle = ActionBarDrawerToggle(this,mainDrawer,
            R.string.app_name,
            R.string.app_name
        )
        actionBarDrawerToggle.syncState()
        navigationView.setNavigationItemSelectedListener {
            val intent = Intent(this,ProfileActivity::class.java)
            startActivity(intent)
            mainDrawer.closeDrawers()
            true
        }
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (actionBarDrawerToggle.onOptionsItemSelected(item)){
            return true
        }
        return super.onOptionsItemSelected(item)
    }
}

以下是我的提问模式:

代码语言:javascript
复制
package com.example.quiz.models

data class Question(
    var description: String = "",
    var option1: String = "",
    var option2: String = "",
    var option3: String = "",
    var option4: String = "",
    var answer: String = "",
    var userAnswer:String=""
)

我的测验模型是-

代码语言:javascript
复制
package com.example.quiz.models

import com.google.firebase.auth.FirebaseAuth

data class Quiz(
    var id: String = "",
    var title: String = "",
    var questions: MutableMap<String, Question> = mutableMapOf()
)

数据库图像:

数据库图像

逻辑猫错误是-

代码语言:javascript
复制
2022-04-24 17:19:04.678 12341-12341/com.example.quiz E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.quiz, PID: 12341
    java.lang.RuntimeException: Could not deserialize object. Can't convert object of type java.lang.String to type com.example.quiz.models.Question (found in field 'questions.title')
        at com.google.firebase.firestore.util.CustomClassMapper.deserializeError(CustomClassMapper.java:568)
        at com.google.firebase.firestore.util.CustomClassMapper.convertBean(CustomClassMapper.java:549)
        at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(CustomClassMapper.java:258)
        at com.google.firebase.firestore.util.CustomClassMapper.deserializeToType(CustomClassMapper.java:194)
        at com.google.firebase.firestore.util.CustomClassMapper.deserializeToParameterizedType(CustomClassMapper.java:296)
        at com.google.firebase.firestore.util.CustomClassMapper.deserializeToType(CustomClassMapper.java:192)
        at com.google.firebase.firestore.util.CustomClassMapper.access$300(CustomClassMapper.java:57)
        at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:775)
        at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:746)
        at com.google.firebase.firestore.util.CustomClassMapper.convertBean(CustomClassMapper.java:547)
        at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(CustomClassMapper.java:258)
        at com.google.firebase.firestore.util.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:103)
        at com.google.firebase.firestore.DocumentSnapshot.toObject(DocumentSnapshot.java:183)
        at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(QueryDocumentSnapshot.java:116)
        at com.google.firebase.firestore.QuerySnapshot.toObjects(QuerySnapshot.java:184)
        at com.google.firebase.firestore.QuerySnapshot.toObjects(QuerySnapshot.java:166)
        at com.example.quiz.activities.MainActivity.setUpFirestore$lambda-4(MainActivity.kt:95)
        at com.example.quiz.activities.MainActivity.$r8$lambda$ALF8Ugv5XcVyBlrGHEr70w5PaxM(Unknown Source:0)
        at com.example.quiz.activities.MainActivity$$ExternalSyntheticLambda5.onEvent(Unknown Source:4)
        at com.google.firebase.firestore.Query.lambda$addSnapshotListenerInternal$2$com-google-firebase-firestore-Query(Query.java:1205)
        at com.google.firebase.firestore.Query$$ExternalSyntheticLambda2.onEvent(Unknown Source:6)
        at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0$com-google-firebase-firestore-core-AsyncEventListener(AsyncEventListener.java:42)
        at com.google.firebase.firestore.core.AsyncEventListener$$ExternalSyntheticLambda0.run(Unknown Source:6)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-26 11:42:56

您将得到以下错误:

无法反序列化对象。不能将java.lang.String类型的对象转换为com.example.quiz.models.Question类型(在字段‘questions.title’中找到)

因为在使用这一行代码时:

代码语言:javascript
复制
Log.d("DATA", value.toObjects(Quiz::class.java).toString())

这意味着您试图将每个文档转换为Quiz类型的对象,这实际上是不可能的。为什么?因为每个文档都应该包含一个questions数组,这个数组应该只由Question对象组成。但这并没有发生,因为该数组还包含一个名为title的字符串。正如我在您的Quiz类中所看到的,标题字段应该是文档中的一个字段,并且而不是应该出现在数组中。要解决这个问题,您必须从数组中移除标题,并将其作为文档中的字段添加。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71986578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档