This is the result of RecyclerView:
Firestore database schema:
this is the code I am using. This only retrieve data like in a image
db.collection("Expenses")
.whereEqualTo("Email",email)
.whereGreaterThanOrEqualTo("Date",MonthFirstDate)
.whereLessThanOrEqualTo("Date",TodayDate)
.orderBy("Date")
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if (!queryDocumentSnapshots.isEmpty()){
expensesArrayList.clear();
List<DocumentSnapshot> list = queryDocumentSnapshots.getDocuments();
for (DocumentSnapshot ds : list){
expenses expenses = ds.toObject(expenses.class);
expensesArrayList.add(expenses);
}
adapter.notifyDataSetChanged();
}
}
})
recyclerview Adapter code
import java.util.ArrayList;
public class expensesAdapter extends RecyclerView.Adapter<expensesAdapter.expHolder> {
private ArrayList<expenses> expensesArrayList;
private Context context;
public expensesAdapter(ArrayList<expenses> expensesArrayList, Context context) {
this.expensesArrayList = expensesArrayList;
this.context = context;
}
@NonNull
@Override
public expensesAdapter.expHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.expensesitems,parent,false);
return new expHolder(v);
}
@Override
public void onBindViewHolder(@NonNull expensesAdapter.expHolder holder, int position) {
expenses expenses = expensesArrayList.get(position);
holder.catName.setText(expenses.getCategory());
holder.catAmont.setText(expenses.getAmount());
}
@Override
public int getItemCount() {
return expensesArrayList.size();
}
class expHolder extends RecyclerView.ViewHolder {
private final TextView catName,catAmont;
public expHolder(@NonNull View itemView) {
super(itemView);
catName = itemView.findViewById(R.id.expCategory);
catAmont =itemView.findViewById(R.id.expAmount);
}
}
}
This is the expenses class
public class expenses {
String Category;
String Date;
String Email;
String Amount;
String Description;
String expID;
public expenses(String category, String date, String email, String amount, String description, String expID) {
Category = category;
Date = date;
Email = email;
Amount = amount;
Description = description;
this.expID = expID;
}
public expenses(){}
public String getCategory() {
return Category;
}
public void setCategory(String category) {
Category = category;
}
public String getDate() {
return Date;
}
public void setDate(String date) {
Date = date;
}
public String getEmail() {
return Email;
}
public void setEmail(String email) {
Email = email;
}
public String getAmount() {
return Amount;
}
public void setAmount(String amount) {
Amount = amount;
}
public String getDescription() {
return Description;
}
public void setDescription(String description) {
Description = description;
}
public String getExpID() {
return expID;
}
public void setExpID(String expID) {
this.expID = expID;
}
}
But i need this kind of result:
I want a category wise Sum amount on recyclerview. In my code its only showing separately.
Please gys help me for figure this out!
2
Answers
This is because for every document in the database collection, you are adding it to your expenses list. You can store all the expenses category wise and then add it to your adapter list.
However, there can be problems with this implementation in case you have similar categories with different names like, phone and Phone, they will be considered different categories. I would suggest you to redesign your implementation with enum classes for categories.
Quick Tips:
The problem in your code lies in the fact that you have in your
expenses
class a field calledCategory
and a getter calledgetCategory(),
which is not correct since Firebase is looking in the database for a field namedcategory
and notCategory
. See the lowercasec
letter vs. capital letterC
?The Firebase SDK maps between your Java object and the JSON properties in the Cloud Firestore based on JavaBean property naming conventions. That being said, there are multiple solutions to solve this problem, but here are the simplest ones:
@PropertyName
annotation in front of the getters, to map the the fields in your class into the name that exists inside the database:P.S. Please also see that I have renamed the class from
expenses
toExpenses
, to the Java Naming Conventions.