0

I am building a calorie counter as part of an Android application and I would like to display the total Grams value of each meal in the front-end. So far I am only retrieving a single child value. How would I add a value to the total amount when a new meal is added?

FoodFragment

           mealRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {

            for (DataSnapshot ds : snapshot.getChildren()) {
                ds.getKey();
                long sum = 0;
                String grams = ds.child("grams").getValue(String.class);

                if (grams == null) {
                    textViewFoodCounter.setText("0");
                } else {
                    sum = sum + Integer.parseInt(grams);
                    textViewFoodCounter.setText(String.valueOf(sum));
                }

                progressBar.setMax(1000); // make dynamic
                ObjectAnimator.ofInt(progressBar, "progress", Integer.parseInt(grams))
                        .setDuration(300)
                        .start();

                Meal data = ds.getValue(Meal.class);
                meals.add(data);
            }

            foodAdapter = new FoodAdapter(meals);
            foodRecyclerView.setAdapter(foodAdapter);
        }

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

        }
    });

AddNewMeal

     logMeal.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String foodName = mealName.getText().toString().trim();
                String calories = caloriesET.getText().toString().trim(); // potentially make this an integer?
                String grams = gramsET.getText().toString().trim(); // potentially make this an integer?
   meal = new Meal(grams, foodName, calories);

                databaseReference.child("meals").child(dateString).push().setValue(meal)
                        .addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if (task.isSuccessful()){
                            Log.d("Event", "onComplete: Successfully added event information to Dog");
                           progressBar.setVisibility(View.GONE);
                            Toast.makeText(AddNewMeal.this, "Successfully added new meal", Toast.LENGTH_LONG).show();
                        } else {
                            Log.d("Event", "Failure - Dog not Created", task.getException());
                            progressBar.setVisibility(View.GONE);
                            Toast.makeText(AddNewMeal.this, "Meal not added, please try again..", Toast.LENGTH_LONG).show();
                        }
                    }
                });

    });

Firebase Hierarchy:

enter image description here

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Caitlin
  • 531
  • 5
  • 19
  • So to understand better, do you want to sum the values of all calories that exist within `12082021`? – Alex Mamo Aug 13 '21 at 06:53
  • I'd like to know how to sum the total grams for each day (`dateString`) @AlexMamo, but I assume the method would be the same for calories also. Sorry for late reply. – Caitlin Aug 13 '21 at 12:17
  • So there are also other dates besides `12082021`? Please show us a more detailed schema. – Alex Mamo Aug 13 '21 at 12:37
  • Each date is logged with that days date using a variable `dateString`, so any meals logged the following day will be logged with a new dateString, and then it is pushed with a `Uid` hope that makes sense! This code is seen above under `AddNewMeal` @AlexMamo – Caitlin Aug 13 '21 at 12:43

1 Answers1

1

To get the total number of grams that exist under each meal of each day, please use the following lines of code:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference mealsRef = rootRef.child("meals");
mealsRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (task.isSuccessful()) {
            int total = 0;
            for (DataSnapshot dateSnapshot : task.getResult().getChildren()) {
                for (DataSnapshot mealSnapshot : dateSnapshot.getChildren()) {
                    String grams = mealSnapshot.child("grams").getValue(String.class);
                    total += Integer.parseInt(grams)
                }
            }
            Log.d("TAG", "total: " + total);
        } else {
            Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
        }
    }
});

According to your screenshot, the result in the logcat will be:

totalCalories: 320
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Hi @AlexMamo, just getting back to this today so I will let you know. Looks promising though! Thanks for your help. – Caitlin Aug 16 '21 at 10:02
  • Ok, Caitlin. Keep me posted ;) – Alex Mamo Aug 16 '21 at 10:06
  • This does work! Need to adjust it as it is taking the total grams for the entire node and not for each daily value (dateString), would I remove the dateSnapshot loop? – Caitlin Aug 16 '21 at 10:34
  • 1
    Good to hear that it worked. If you need the sum for a single day, you need to create a new reference that points to a particular day and use a single loop, **not** two. – Alex Mamo Aug 16 '21 at 10:39
  • Perfect, that's what I thought. Thanks for your help :) – Caitlin Aug 16 '21 at 10:41