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

Android Studio Firebase购物车存商品Key后查询返回Null问题

问题诊断
  1. 数据库路径错误:你的Inventory节点是嵌套在对应卖家的User节点下,并非根节点的独立Inventory,之前getReference("Inventory").child(CartItemId)的路径完全错误,找不到数据自然返回null。
  2. 数据解析逻辑错误:每个CartItemId对应一个完整的商品对象,无需遍历快照子节点,直接从当前快照解析即可——遍历子节点只会拿到单个字段(如cat、price),无法映射为CartInventory对象。
  3. 缺失商品所属卖家信息:当前Cart节点仅存储商品Key,但不知道该商品属于哪个卖家的User节点,导致无法准确定位商品路径。

解决方案

推荐方案:修改Cart节点存储结构(更高效可靠)

先将Cart节点的存储格式从"-NOLDZyNHqm_FPJxHEil": "-NOLDZyNHqm_FPJxHEil"改为同时存储卖家ID和商品ID:

"Cart": {
  "-NOLDZyNHqm_FPJxHEil": {
    "itemId": "-NOLDZyNHqm_FPJxHEil",
    "sellerId": "Azml0TbC5MfqNdBjZYrOzdhcDhW2"
  }
}

然后修改查询代码:

user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
    String userId = user.getUid();
    DatabaseReference cartRef = FirebaseDatabase.getInstance().getReference("User").child(userId).child("Cart");

    cartRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
            // 解析Cart中的商品信息,包含卖家ID和商品ID
            CartItem cartItem = snapshot.getValue(CartItem.class);
            if (cartItem != null) {
                String sellerId = cartItem.getSellerId();
                String itemId = cartItem.getItemId();

                // 正确的商品路径:User -> 卖家ID -> Inventory -> 商品ID
                DatabaseReference itemRef = FirebaseDatabase.getInstance().getReference("User")
                        .child(sellerId)
                        .child("Inventory")
                        .child(itemId);

                // 使用ValueEventListener获取完整商品数据
                itemRef.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        if (snapshot.exists()) {
                            CartInventory inventory = snapshot.getValue(CartInventory.class);
                            if (inventory != null) {
                                inventory.setKey(itemId);
                                // 避免重复添加
                                boolean isExists = cartArrayList.stream().anyMatch(i -> i.getKey().equals(itemId));
                                if (!isExists) {
                                    cartArrayList.add(inventory);
                                    runOnUiThread(() -> cartAdapter.notifyDataSetChanged());
                                }
                            }
                        }
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {
                        // 处理查询错误,比如打印日志
                    }
                });
            }
        }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot snapshot) {
            // 移除购物车商品时更新列表
            CartItem cartItem = snapshot.getValue(CartItem.class);
            if (cartItem != null) {
                String itemId = cartItem.getItemId();
                cartArrayList.removeIf(inventory -> inventory.getKey().equals(itemId));
                runOnUiThread(() -> cartAdapter.notifyDataSetChanged());
            }
        }

        // 实现其他ChildEventListener方法
        @Override
        public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {}
        @Override
        public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {}
        @Override
        public void onCancelled(@NonNull DatabaseError error) {}
    });
}

对应的CartItem实体类:

public class CartItem {
    private String itemId;
    private String sellerId;

    // Firebase需要空构造函数
    public CartItem() {}

    public CartItem(String itemId, String sellerId) {
        this.itemId = itemId;
        this.sellerId = sellerId;
    }

    // Getter和Setter方法
    public String getItemId() { return itemId; }
    public void setItemId(String itemId) { this.itemId = itemId; }
    public String getSellerId() { return sellerId; }
    public void setSellerId(String sellerId) { this.sellerId = sellerId; }
}

备选方案:不修改Cart存储结构(效率较低)

如果暂时不想改存储结构,可以遍历所有用户的Inventory查找商品,但用户量较大时性能会受影响:

user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
    String userId = user.getUid();
    DatabaseReference cartRef = FirebaseDatabase.getInstance().getReference("User").child(userId).child("Cart");

    cartRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
            String itemId = snapshot.getKey();

            // 遍历所有用户的Inventory找对应商品
            DatabaseReference allUsersRef = FirebaseDatabase.getInstance().getReference("User");
            allUsersRef.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    for (DataSnapshot userSnapshot : snapshot.getChildren()) {
                        DataSnapshot inventorySnapshot = userSnapshot.child("Inventory").child(itemId);
                        if (inventorySnapshot.exists()) {
                            CartInventory inventory = inventorySnapshot.getValue(CartInventory.class);
                            if (inventory != null) {
                                inventory.setKey(itemId);
                                cartArrayList.add(inventory);
                                runOnUiThread(() -> cartAdapter.notifyDataSetChanged());
                                break; // 找到后停止遍历
                            }
                        }
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {}
            });
        }

        // 其他方法省略...
    });
}

注意事项
  • 确保CartInventory实体类的字段名与数据库字段完全一致,若字段名不一致需添加@PropertyName注解(比如数据库是item_name,实体类用itemName的话,需标注@PropertyName("item_name"))。
  • 调用notifyDataSetChanged()时需确保在主线程执行,可使用runOnUiThread包裹。
  • 在Fragment或Activity销毁时,记得移除Firebase监听器,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 07:15:00