You need to enable JavaScript to run this app. 如何将Firestore返回的$document.data转换为可用于ListView的可用格式
优惠活动
大模型
产品
解决方案
定价
更多

如何将Firestore返回的$document.data转换为可用于ListView的可用格式

实现方案

步骤1:创建匹配Firestore字段的Kotlin数据实体类

先定义和返回字段完全对应的实体类,后续所有逻辑都可以直接用该类的对象操作,复用性最高:

import com.google.firebase.firestore.PropertyName
import androidx.annotation.Keep

@Keep // 防止混淆导致字段映射失败
data class User(
    var id: String = "",
    var lastName: String = "",
    var firstName: String = "",
    var image: String = "",
    var gender: String = "",
    var organization: String = "",
    var profileCompleted: Int = 0,
    var mobile: Long = 0,
    // 字段带空格需要用PropertyName指定映射的字段名
    @PropertyName("blood group")
    var bloodGroup: String = "",
    var email: String = "",
    var B: String = ""
)

注意所有字段都要设置默认值,否则Firestore映射的时候会抛出异常。

步骤2:修改查询回调,将DocumentSnapshot转换为实体类对象

修改你原来的成功回调逻辑,把查询到的文档转成User对象,存入列表供后续使用:

// 先定义存储查询结果的全局列表
private val userList = mutableListOf<User>()

private val mFireStore = FirebaseFirestore.getInstance()
mFireStore.collection("Users")
    .whereEqualTo("lastName","H")
    .whereEqualTo("firstName", "Uc")
    .get()
    .addOnSuccessListener{ documents ->
        // 先清空旧数据避免重复
        userList.clear()
        for(document in documents){
            // 核心转换逻辑,直接把document映射为User对象
            val user = document.toObject(User::class.java)
            userList.add(user)
            Log.d("TAG","${user.id}=>${user.email}")
        }
        // 数据获取完成后,通知ListView刷新
        userAdapter.notifyDataSetChanged()
        Toast.makeText(applicationContext, "查询到${userList.size}条数据", Toast.LENGTH_LONG).show()
    }
    .addOnFailureListener{exception ->
        Log.w("TAG","Error getting documents:",exception)
        Toast.makeText(applicationContext, "获取数据失败", Toast.LENGTH_LONG).show()
    }

步骤3:实现ListView的自定义适配器

你可以根据自己的布局需求实现适配器,示例代码如下:

class UserAdapter(context: Context, private val dataList: List<User>) : BaseAdapter() {
    private val inflater = LayoutInflater.from(context)

    override fun getCount(): Int = dataList.size

    override fun getItem(position: Int): Any = dataList[position]

    override fun getItemId(position: Int): Long = position.toLong()

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val view: View
        val viewHolder: ViewHolder
        if (convertView == null) {
            // 替换为你自己的列表项布局
            view = inflater.inflate(R.layout.item_user, parent, false)
            viewHolder = ViewHolder(view)
            view.tag = viewHolder
        } else {
            view = convertView
            viewHolder = view.tag as ViewHolder
        }
        val user = dataList[position]
        // 给控件赋值,替换为你自己的控件ID
        viewHolder.tvName.text = "${user.firstName} ${user.lastName}"
        viewHolder.tvEmail.text = user.email
        viewHolder.tvBloodGroup.text = user.bloodGroup
        return view
    }

    class ViewHolder(itemView: View) {
        // 替换为你自己布局里的控件
        val tvName: TextView = itemView.findViewById(R.id.tv_name)
        val tvEmail: TextView = itemView.findViewById(R.id.tv_email)
        val tvBloodGroup: TextView = itemView.findViewById(R.id.tv_blood_group)
    }
}

步骤4:绑定适配器到ListView

在Activity的onCreate方法里提前初始化适配器并绑定到ListView:

// 全局变量
private lateinit var userAdapter: UserAdapter

// onCreate里执行
userAdapter = UserAdapter(this, userList)
// 替换为你布局里的ListView ID
listView.adapter = userAdapter

完成以上步骤后,每次查询到新数据都会自动刷新ListView显示内容,同时userList里的User对象可以直接在其他业务逻辑里复用。

内容的提问来源于stack exchange,提问作者user15880034

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 15:42:01