Firebase实时数据库读取报错:无法将String转为Cartmodel
Firebase Realtime Database 数据读取转换错误解决
错误信息
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.register.Model.Cartmodel
写入数据代码
private void addtocart() { String saveCurrentDate, saveCurrentTime; Calendar calForDate = Calendar.getInstance(); SimpleDateFormat currentDate = new SimpleDateFormat("MMM dd, yyyy"); saveCurrentDate = currentDate.format(calForDate.getTime()); SimpleDateFormat currentTime = new SimpleDateFormat("HH:mm:ss a"); saveCurrentTime = currentTime.format(calForDate.getTime()); final DatabaseReference cartListRef = FirebaseDatabase.getInstance().getReference().child("Cart List"); String timestamp = String.valueOf(System.currentTimeMillis()); double price = Double.parseDouble(emailholder.getText().toString().replace("₹", "")); double quantityValue = Double.parseDouble(quantity.getText().toString()); double result = price * quantityValue; Intent intent = getIntent(); String purl = intent.getStringExtra("purl"); final HashMap<String, Object> cartMap = new HashMap<>(); cartMap.put("productName",nameholder.getText().toString()); cartMap.put("productPrice",emailholder.getText().toString()); cartMap.put("productImage", purl); cartMap.put("date",saveCurrentDate); cartMap.put("time",saveCurrentTime); cartMap.put("quantity",quantity.getText().toString()); cartMap.put("totalPrice",result); String currentUserPhoneNumber = Paper.book().read(Prevalent.UserPhoneKey); cartListRef.child("currentUserPhoneNumber") //.child(timestamp) .updateChildren(cartMap) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { Toast.makeText(details.this, "Added to cart", Toast.LENGTH_SHORT).show(); } }); }
Model类代码
package com.example.register.Model; public class Cartmodel { String date; String productImage; static String productName; String productPrice; static String quantity; String time; static String totalPrice; public Cartmodel() { } public Cartmodel(String date, String productImage, String productName, String quantity, String time, String totalPrice,String productPrice) { this.date = date; this.productImage = productImage; this.productName = productName; this.quantity = quantity; this.time = time; this.totalPrice = totalPrice; this.productPrice = productPrice; } public String getProductPrice() { return productPrice; } public void setProductPrice(String productPrice) { this.productPrice = productPrice; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getProductImage() { return productImage; } public void setProductImage(String productImage) { this.productImage = productImage; } public static String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public static String getQuantity() { return quantity; } public void setQuantity(String quantity) { this.quantity = quantity; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } public static String getTotalPrice() { return totalPrice; } public void setTotalPrice(String totalPrice) { this.totalPrice = totalPrice; } }
读取数据代码
@Override protected void onStart() { super.onStart(); String currentUserPhoneNumber = Paper.book().read(UserPhoneKey); String timestamp = String.valueOf(System.currentTimeMillis()); final DatabaseReference cartListRef = FirebaseDatabase.getInstance().getReference().child("Cart List"); FirebaseRecyclerOptions<Cartmodel> options = new FirebaseRecyclerOptions.Builder<Cartmodel>() .setQuery(cartListRef.child("currentUserPhoneNumber") /**.child(timestamp)**/,Cartmodel.class).build(); FirebaseRecyclerAdapter<Cartmodel, CartViewHolder> adapter =new FirebaseRecyclerAdapter<Cartmodel, CartViewHolder>(options) { @Override protected void onBindViewHolder(@NonNull CartViewHolder holder, int position, @NonNull Cartmodel model) { holder.TxtQunatity.setText(Cartmodel.getQuantity()); holder.TxtProductPrice.setText(Cartmodel.getProductName()); holder.TxtProductName.setText(Cartmodel.getTotalPrice()); } @NonNull @Override public CartViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_row,parent,false); CartViewHolder holder = new CartViewHolder(view); return holder; } }; recyclerView.setAdapter(adapter); adapter.startListening(); }
数据库结构
"Cart List": { "currentUserPhoneNumber": { "date": "Feb 15, 2023", "productImage": "https://images.jdmagicbox.com/comp/mumbai/z3/022pxx22.xx22.181204184809.b5z3/catalogue/burger-king-santacruz-east-mumbai-burger-king-3hofjz4vmz.jpg", "productName": "Chicken Burger", "productPrice": "₹₹350", "quantity": "3", "time": "15:08:00 PM", "totalPrice": 1050 } }
问题原因及解决方案
核心问题
- 数据结构不匹配:数据库中
currentUserPhoneNumber节点直接存储单个购物车项的字段,而FirebaseRecyclerAdapter期望查询的是多个Cartmodel对象的列表(每个子节点对应一个完整对象)。 - Model类静态字段错误:
productName、quantity、totalPrice被定义为静态字段,导致Gson无法正确映射实例数据,且所有实例共享同一值。 - 读取逻辑错误:
onBindViewHolder中调用静态方法获取字段,而非使用传入的model实例;同时查询路径未指向用户专属节点,且未匹配列表结构。 - 数据类型不匹配:数据库中
totalPrice是数字类型,但Model类中定义为String类型,解析时会报错。
修复步骤
1. 修正Model类,移除静态字段并统一数据类型
package com.example.register.Model; public class Cartmodel { String date; String productImage; String productName; String productPrice; String quantity; String time; double totalPrice; public Cartmodel() { } public Cartmodel(String date, String productImage, String productName, String quantity, String time, double totalPrice, String productPrice) { this.date = date; this.productImage = productImage; this.productName = productName; this.quantity = quantity; this.time = time; this.totalPrice = totalPrice; this.productPrice = productPrice; } public String getProductPrice() { return productPrice; } public void setProductPrice(String productPrice) { this.productPrice = productPrice; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getProductImage() { return productImage; } public void setProductImage(String productImage) { this.productImage = productImage; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public String getQuantity() { return quantity; } public void setQuantity(String quantity) { this.quantity = quantity; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } public double getTotalPrice() { return totalPrice; } public void setTotalPrice(double totalPrice) { this.totalPrice = totalPrice; } }
2. 修正写入数据的结构,区分用户并存储为列表形式
// 替换写入逻辑中的节点路径部分 cartListRef.child(currentUserPhoneNumber) // 使用变量存储用户手机号,而非固定字符串 .child(timestamp) // 用timestamp作为每个购物车项的唯一标识 .updateChildren(cartMap) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { Toast.makeText(details.this, "Added to cart", Toast.LENGTH_SHORT).show(); } });
3. 修正读取数据的逻辑,匹配列表结构并使用实例字段
@Override protected void onStart() { super.onStart(); String currentUserPhoneNumber = Paper.book().read(UserPhoneKey); final DatabaseReference cartListRef = FirebaseDatabase.getInstance().getReference().child("Cart List"); FirebaseRecyclerOptions<Cartmodel> options = new FirebaseRecyclerOptions.Builder<Cartmodel>() // 查询用户节点下的所有购物车项子节点 .setQuery(cartListRef.child(currentUserPhoneNumber), Cartmodel.class).build(); FirebaseRecyclerAdapter<Cartmodel, CartViewHolder> adapter =new FirebaseRecyclerAdapter<Cartmodel, CartViewHolder>(options) { @Override protected void onBindViewHolder(@NonNull CartViewHolder holder, int position, @NonNull Cartmodel model) { // 使用model实例的getter方法获取字段值 holder.TxtQunatity.setText(model.getQuantity()); holder.TxtProductPrice.setText(model.getProductPrice()); holder.TxtProductName.setText(model.getProductName()); // 如果需要显示总价,可转成字符串:String.valueOf(model.getTotalPrice()) } @NonNull @Override public CartViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_row,parent,false); CartViewHolder holder = new CartViewHolder(view); return holder; } }; recyclerView.setAdapter(adapter); adapter.startListening(); }
内容的提问来源于stack exchange,提问作者Aditya Singh Rajput
相关产品推荐
相关产品推荐

