I've searched everything for this error and this is my first time asking a question. And I'm trying to do a Nested RecyclerView for my Shipments Page on my app I don't know what's to my problem with my code. I tried everything and it keeps saying that's the error. I don't know what to do
Here is the error at the Logcat
2022-08-29 23:31:23.029 16114-16114/com.example.testingeverything E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.testingeverything, PID: 16114
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.testingeverything.ShippingDetail
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:436)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(CustomClassMapper.java:179)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToParameterizedType(CustomClassMapper.java:265)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(CustomClassMapper.java:177)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.access$100(CustomClassMapper.java:48)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:593)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:563)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:433)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80)
at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
at com.example.testingeverything.ShipmentsActivity$1.onDataChange(ShipmentsActivity.java:42)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
ShipmentsActivity.java
public class ShipmentsActivity extends AppCompatActivity {
String userName = MainActivity.userName;
RecyclerView shipmentsRecyclerView;
ShipmentsActivityAdapter shipmentsActivityAdapter;
ArrayList<Shipments> shipments_list;
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference databaseReference = rootRef.child("Users").child(userName).child(userName "Shipments");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shipments);
shipmentsRecyclerView = findViewById(R.id.shipments_recycler_view);
shipmentsRecyclerView.setHasFixedSize(true);
shipments_list = new ArrayList<>();
shipmentsActivityAdapter = new ShipmentsActivityAdapter(this);
shipmentsActivityAdapter.setShipments(shipments_list);
shipmentsRecyclerView.setAdapter(shipmentsActivityAdapter);
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot snapshot1 : snapshot.getChildren()) {
//This is where the error is
Shipments shipments = snapshot1.getValue(Shipments.class);
shipments_list.add(shipments);
}
shipmentsActivityAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
Shipments.java
public class Shipments {
private Map<String, ShippingDetail> details;
private Map<String, ShippingProduct> products;
public Shipments(Map<String, ShippingDetail> details, Map<String, ShippingProduct> products) {
this.details = details;
this.products = products;
}
public Shipments() {
}
public Map<String, ShippingDetail> getDetails() {
return details;
}
public void setDetails(Map<String, ShippingDetail> details) {
this.details = details;
}
public Map<String, ShippingProduct> getProducts() {
return products;
}
public void setProducts(Map<String, ShippingProduct> products) {
this.products = products;
}
}
ShippingDetail.java
public class ShippingDetail {
private String emailaddress;
private String facebook;
private String fulladdress;
private String fullname;
private String paymentmethod;
private String phonenumber;
private String postalcode;
private String schedule;
private String region;
private boolean setenablebutton;
private String status;
private int totalprice;
private String tracknumber;
public ShippingDetail(String emailaddress, String facebook, String fulladdress, String fullname, String paymentmethod, String phonenumber, String postalcode, String schedule, String region, boolean setenablebutton, String status, int totalprice, String tracknumber) {
this.emailaddress = emailaddress;
this.facebook = facebook;
this.fulladdress = fulladdress;
this.fullname = fullname;
this.paymentmethod = paymentmethod;
this.phonenumber = phonenumber;
this.postalcode = postalcode;
this.schedule = schedule;
this.region = region;
this.setenablebutton = setenablebutton;
this.status = status;
this.totalprice = totalprice;
this.tracknumber = tracknumber;
}
public ShippingDetail(){} //Below are getters and setters
ShipmentsActivityAdapter.java
public class ShipmentsActivityAdapter extends RecyclerView.Adapter<ShipmentsActivityAdapter.ViewHolder> {
private String userName = MainActivity.userName;
private List<Shipments> shipments = new ArrayList<>();
private Context context;
public ShipmentsActivityAdapter (Context context){this.context = context;}
public void setShipments (List<Shipments> shipments){
this.shipments = shipments;
notifyDataSetChanged();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private RecyclerView productsRecyclerView;
private RecyclerView detailsRecyclerView;
private Button cancelButton;
private List<ShippingProduct> shippingProducts_list;
private List<ShippingDetail> shipmentsDetail_list;
private DatabaseReference databaseForDetailsReference = FirebaseDatabase.getInstance().getReference().child("Users").child(userName).child(userName "Shipments");
private DatabaseReference databaseForProductsReference = FirebaseDatabase.getInstance().getReference().child("Users").child(userName).child(userName "Shipments");
public ViewHolder(@NonNull View itemView) {
super(itemView);
productsRecyclerView = itemView.findViewById(R.id.products_recyclerView);
detailsRecyclerView = itemView.findViewById(R.id.details_recyclerView);
cancelButton = itemView.findViewById(R.id.cancel_btn);
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fourth_activity_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ShippingDetailAdapter detailAdapter = new ShippingDetailAdapter(context);
ShippingProductAdapter productAdapter = new ShippingProductAdapter(context);
holder.shippingProducts_list = new ArrayList<>();
holder.shipmentsDetail_list = new ArrayList<>();
holder.detailsRecyclerView.setHasFixedSize(true);
holder.productsRecyclerView.setHasFixedSize(true);
holder.detailsRecyclerView.setLayoutManager(new LinearLayoutManager(context));
holder.productsRecyclerView.setLayoutManager(new LinearLayoutManager(context));
holder.detailsRecyclerView.setAdapter(detailAdapter);
holder.productsRecyclerView.setAdapter(productAdapter);
holder.databaseForDetailsReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot snapshot1 : snapshot.getChildren()){
String getTheKey = snapshot1.getKey();
ShippingDetail shippingDetail = snapshot1.child(getTheKey).getValue(ShippingDetail.class);
holder.shipmentsDetail_list.add(shippingDetail);
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
holder.databaseForProductsReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot snapshot1 : snapshot.getChildren()){
String getTheKey = snapshot1.getKey();
ShippingProduct shippingProduct = snapshot1.child(getTheKey).getValue(ShippingProduct.class);
holder.shippingProducts_list.add(shippingProduct);
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
@Override
public int getItemCount() {
return shipments.size();
}
}
This is the Database Structure
CodePudding user response:
When you attach a listener to the following reference:
rootRef.child("Users").child(userName).child(userName "Shipments");
And you're looping through the results, you aren't getting ShippingDetail
objects, you're getting just a string called details
, and hence the error. Why? Because under johnnyShipments
node, there is a single direct child called details
.
To solve this, you have to remove the extra details
level, which in my opinion is not required, and this error will go away.