尝试获取 Firebase 云数据库数据并将其显示在 RecyclerView 中的片段中

Posted

技术标签:

【中文标题】尝试获取 Firebase 云数据库数据并将其显示在 RecyclerView 中的片段中【英文标题】:Trying to fetch Firebase Cloud Database data and show it in RecyclerView in a fragment 【发布时间】:2021-11-07 10:03:17 【问题描述】:

我正在尝试从 Firebase Cloud Datastore 获取 RecyclerView 中的数据。但是当我这样做时,我收到以下错误:

java.lang.RuntimeException:无法反序列化对象。类 models.Post 没有定义无参数构造函数。如果你使用 ProGuard,请确保这些构造函数没有被剥离

这是我正在使用的片段:

class forumFragment : Fragment(R.layout.fragment_forum)  

    private lateinit var myadapter: MyAdapter

    private lateinit var fragmentForumBinding: FragmentForumBinding

    private lateinit var userArrayList: ArrayList<itemViewModel>
    private lateinit var postDao: postDao



    //val mAuth= Firebase.auth.currentUser
    val mAuth : FirebaseUser? = FirebaseAuth.getInstance().currentUser

    //private lateinit var recyclerView:RecyclerView



    private var mDocReference: DocumentReference ?=null
    //= FirebaseFirestore.getInstance().collection(/).document()
    /*override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
       // recyclerView = view?.findViewById(R.id.recyclerViewForum)!!
        val binding = FragmentForumBinding.inflate(layoutInflater)
        fragmentForumBinding = binding

        setUpRecyclerView()
    */

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)

        val binding = FragmentForumBinding.bind(view)
        fragmentForumBinding = binding

        setUpRecyclerView()
    

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View 
        val view: View = inflater.inflate(R.layout.fragment_forum, container, false)

        val fabButtom = view.findViewById<FloatingActionButton>(R.id.fabSave)

        fabButtom.setOnClickListener
            if (mAuth !=null)
                fabButtom.visibility = View.INVISIBLE
                fragmentManager?.beginTransaction()?.addToBackStack(null)?.replace(R.id.forumFragment , addPost())?.commit()
                //val navControl = findNavController(R.id.forumFragment)
            
            else
             Toast.makeText(activity ,"Please login to make a query!" , Toast.LENGTH_SHORT).show()
            

        

        return view

        

    private fun setUpRecyclerView() 

       // val recyclerView = view?.findViewById<RecyclerView>(R.id.recyclerViewForum)
        postDao = postDao()

        val postsCollection = postDao.postCollection
        val query = postsCollection.orderBy("createdAt" , Query.Direction.DESCENDING)
        val firestoreRecyclerOptions = FirestoreRecyclerOptions.Builder<Post>().setQuery(query , Post::class.java).build()

        myadapter = MyAdapter(firestoreRecyclerOptions)



        fragmentForumBinding.recyclerViewForum.adapter = myadapter
        fragmentForumBinding.recyclerViewForum.layoutManager = LinearLayoutManager(activity)

    

    override fun onStart() 
        super.onStart()

        myadapter.startListening()
    

    override fun onStop() 
        super.onStop()
        myadapter.stopListening()
    

models.Post 类看起来像这样:

data class Post (val descrription: String = "",
                 val createdBy: User = User(),

                 val  currentTime:String = "",
                 val currentDate:String = "",
                 val createdAt:Long )

【问题讨论】:

不清楚您使用的是 Cloud Firestore(默认)、Datatore 模式下的 Cloud Firestore 还是实时数据库,因为您可以互换使用这些术语。 以后格式化代码块时,需要使用反引号字符`(通常在波浪号~键上)而不是撇号'。内联代码一个反引号,代码块三个反引号(在自己的行上)。 【参考方案1】:

为了让 Firebase SDK 将远程数据转换为所需的模型类,它需要有一个无参数的构造函数。

注意:我已将下面的descrription 更正为description

在您当前的models.Post 类中,它没有createdAt 的默认值:

data class Post (val description: String = "",
                 val createdBy: User = User(),
                 val currentTime: String = "",
                 val currentDate: String = "",
                 val createdAt: Long ) // <-- missing = 0L

应该是这样的:

data class Post (val description: String = "",
                 val createdBy: User = User(),
                 val currentTime: String = "",
                 val currentDate: String = "",
                 val createdAt: Long = 0L )

或者,您可以对models.Post 使用以下声明:

data class Post (val description: String,
                 val createdBy: User,
                 val currentTime: String,
                 val currentDate: String,
                 val createdAt: Long) 
  // empty constructor for Firebase with dummy data
  constructor(): this("", User(), "", "", 0L)

【讨论】:

以上是关于尝试获取 Firebase 云数据库数据并将其显示在 RecyclerView 中的片段中的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Auth:我想获取当前用户个人资料照片并将其上传到 Firebase 数据库或存储

如何在firebase(swift)中获取子节点的值,并将其显示在视图控制器的标签中

从firebase获取数据并将其返回到主线程[重复]

从 firebase 基于云的数据库中获取用户数据并转换为字典

如何获取当前的 Firebase UID 并将其写入实时数据库?

从 firebase 检索数据并将其显示在可扩展的 recyclerview 中