You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Firebase Firestore拉取数据加载到RecyclerView时App崩溃如何解决

崩溃根因

日志已经明确指出问题核心:Firebase Firestore在将数据库文档反序列化映射为Item实体类对象时,检测到name属性存在大小写冲突的字段或者访问方法。
Firestore的实体类映射逻辑默认不区分大小写匹配字段名,触发该错误的常见场景:

  • Item类中同时声明了name和Name两个大小写不同的同名字段
  • 字段名与getter/setter命名不符合JavaBean规范,比如字段声明为name但存在getNAme()这类大小写不匹配的访问方法
  • 结合你提供的Firestore数据截图,数据库中的字段是首字母大写的Name、Description,如果你的Item类字段命名和数据库字段大小写不匹配,同时没有显式指定映射关系,也可能触发该冲突。
修复方案

1. 修正Item实体类定义

首先确认Item类没有重复的同名字段,同时保证空构造方法存在(Firestore反序列化强制要求公共无参构造),有两种可选的映射方案:

方案A:字段名和Firestore字段完全对齐

public class Item {
    // 字段名和数据库里的首字母大写格式完全一致
    private String Name;
    private String Description;

    // 必须保留公共无参构造
    public Item() {}
    // 自定义构造方法
    public Item(String name, String desc) {
        this.Name = name;
        this.Description = desc;
    }

    // getter/setter要和字段名匹配
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public String getDescription() {
        return Description;
    }
    public void setDescription(String description) {
        Description = description;
    }
}

方案B:用注解显式绑定字段映射

如果你想保持代码里的小驼峰命名规范,可以用@PropertyName注解显式指定对应Firestore的字段名:

import com.google.firebase.firestore.PropertyName;

public class Item {
    @PropertyName("Name") // 显式绑定Firestore中的Name字段
    private String name;
    @PropertyName("Description") // 显式绑定Firestore中的Description字段
    private String description;

    public Item() {}
    public Item(String name, String description) {
        this.name = name;
        this.description = description;
    }

    // 正常写小驼峰的getter/setter即可
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}

2. 优化现有业务代码

你当前把adapter.notifyDataSetChanged()放在遍历循环内部,会导致每加一条数据就刷新一次列表,建议移到循环外部,同时记得关闭进度弹窗:

private void EventChangeListener() {
    db.collection("Foods")
            .addSnapshotListener(new EventListener<QuerySnapshot>() {
                @Override
                public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
                    if (error != null){
                        Toast.makeText(MainActivity.this, "Database Error " + error.getMessage(), Toast.LENGTH_SHORT).show();
                        if (pD.isShowing()) pD.dismiss();
                        return;
                    }
                    // 先清空旧数据避免重复加载
                    itemsList.clear();
                    for (DocumentChange dc : value.getDocumentChanges()){
                        if(dc.getType() == DocumentChange.Type.ADDED){
                            itemsList.add(dc.getDocument().toObject(Item.class));
                        }
                    }
                    // 遍历完成后统一刷新列表
                    adapter.notifyDataSetChanged();
                    // 关闭进度弹窗
                    if (pD.isShowing()) pD.dismiss();
                }
            });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:15:02