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

如何根据Firebase唯一Key在RecyclerView中匹配展示指定账单数据?

解决FirebaseRecyclerAdapter添加.child(keyValue)后崩溃的问题

首先咱们来拆解崩溃的核心原因:
你原本的mRef = FirebaseDatabase.getInstance().getReference().child("Bills")指向的是一个包含多个账单节点的集合,FirebaseRecyclerAdapter就是为处理这类列表数据设计的,所以能正常展示所有账单。

但当你加上.child(keyValue)后,mRef就指向了单个账单的具体节点(比如截图里的-N...xxx层级),此时这个节点是单一的DataModel对象,而非列表集合。FirebaseRecyclerAdapter只能解析列表类型的数据源,无法处理单个对象,因此直接触发崩溃。

另外要提前做校验:如果Intent传递的key为空,.child(keyValue)会变成.child(null),同样会导致崩溃,所以第一步必须先判断keyValue的有效性。

下面给你两种解决方案,可根据需求选择:


方案一:直接展示单个账单(无需RecyclerView)

如果只需要展示匹配key的这一个账单,完全没必要用RecyclerView,直接读取单个节点数据绑定到布局控件即可:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_data_save);
    
    Intent intent = getIntent();
    if(intent == null || intent.getStringExtra("key") == null) {
        // 处理key为空的异常情况
        Toast.makeText(this, "无效的账单Key", Toast.LENGTH_SHORT).show();
        finish();
        return;
    }
    keyValue = intent.getStringExtra("key");

    // 获取单个账单的数据库引用
    DatabaseReference singleBillRef = FirebaseDatabase.getInstance().getReference()
            .child("Bills").child(keyValue);

    // 读取单个账单数据
    singleBillRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if(snapshot.exists()) {
                DataModel model = snapshot.getValue(DataModel.class);
                // 直接绑定布局中的TextView
                TextView billNoTv = findViewById(R.id.receiptBillNo);
                TextView storeNameTv = findViewById(R.id.receiptStoreName);
                TextView dateTv = findViewById(R.id.receiptDate);
                TextView timeTv = findViewById(R.id.receiptTime);
                TextView totalTv = findViewById(R.id.receiptTotal);
                
                billNoTv.setText("Bill No : " + model.getBillNo());
                storeNameTv.setText("Store Name : " + model.getCompany());
                dateTv.setText("Date : " + model.getDate());
                timeTv.setText("Time : " + model.getTime());
                totalTv.setText("Total : " + model.getTotal());
            } else {
                Toast.makeText(DataSaveActivity.this, "未找到对应账单", Toast.LENGTH_SHORT).show();
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            Toast.makeText(DataSaveActivity.this, "读取数据失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

方案二:用RecyclerView展示单个匹配项(保留列表结构)

如果一定要保留RecyclerView(比如后续可能扩展展示多个匹配账单),可以用orderByKey().equalTo(keyValue)构建查询,这样返回的是包含单个元素的列表,FirebaseRecyclerAdapter就能正常处理:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_data_save);
    mReceipt = findViewById(R.id.othersRecycler);
    mReceipt.setLayoutManager(new LinearLayoutManager(this));

    Intent intent = getIntent();
    if(intent == null || intent.getStringExtra("key") == null) {
        Toast.makeText(this, "无效的账单Key", Toast.LENGTH_SHORT).show();
        finish();
        return;
    }
    keyValue = intent.getStringExtra("key");

    // 构建查询:筛选出key与keyValue匹配的账单
    Query billQuery = FirebaseDatabase.getInstance().getReference()
            .child("Bills")
            .orderByKey()
            .equalTo(keyValue);

    // 使用Query作为数据源初始化适配器
    FirebaseRecyclerAdapter<DataModel, ReceiptViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<DataModel, ReceiptViewHolder>
            (DataModel.class, R.layout.reciept_row, ReceiptViewHolder.class, billQuery){
        @Override
        protected void populateViewHolder(ReceiptViewHolder viewHolder,DataModel model, int position) {
            viewHolder.setBillNo("Bill No : " + model.getBillNo());
            viewHolder.setStoreName("Store Name : " + model.getCompany());
            viewHolder.setDate("Date : " + model.getDate());
            viewHolder.setTime("Time : " + model.getTime());
            viewHolder.setBillTotal("Total : " + model.getTotal());
        }
    };
    mReceipt.setAdapter(firebaseRecyclerAdapter);
}

额外注意:请确保你的DataModel类字段与Firebase节点中的字段完全对应(包括大小写),否则会出现数据解析失败的问题。

内容的提问来源于stack exchange,提问作者mav-raj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:20:33