0

Hello everyone i am new on android programming. i have a problem about passind data out of ondatachange method. as you can see below i have 2 queries get data from firebase query1 gets incomes and query gets data outcomes.

so my problem is total incomes (toplamgelir) and total outcomes (toplamgider) transfer to outside of these queries.

when i want to make result from (totalincomes -minus- totaloutcomes = result) it doesnt show anything. how can i do that ? i will be appreciate if you show me the way

thank you in advance for your helps.

double toplamgelir, toplamgider;

 Query query1 = myRef.orderByChild("gelirZaman")
.startAt(getStartOfDay(today).getTime())
.endAt(getEndOfDay(today).getTime());

    query1.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            for (DataSnapshot d : snapshot.getChildren()) {
                Gelirler gelirler = d.getValue(Gelirler.class);
                gelirler.setGelirid(d.getKey());
                toplamgelir = +gelirler.getGelirTutar();
            }
            TVbugungeliristoc.setText(String.valueOf(toplamgelir) + " TL");
        }

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

    Query query2 = myRef2.orderByChild("giderZaman").startAt(getStartOfDay(today).getTime()).endAt(getEndOfDay(today).getTime());
    query2.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            for (DataSnapshot d : snapshot.getChildren()) {
                Giderler giderler = d.getValue(Giderler.class);
                giderler.setGiderid(d.getKey());
                toplamgider = +giderler.getGiderTutar();
            }
            TVbugungideristoc.setText(String.valueOf(toplamgider) + " TL");
        }

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


    double result = (toplamgelir-toplamgider);

    //textview below shows income-outcome = acquired surplus

    TVbugunKarZararistoc.setText(String.valueOf(result));
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
anasdmr
  • 31
  • 3

1 Answers1

1

The problem is not so much where you access the data, but when you access it. By the time your double result = (toplamgelir-toplamgider) runs, the onDataChange methods haven't run yet. If you add some logging, or run in a debugger, you can most easily see that.

Instead of reexplaining why this is, I recommend reading getContactsFromFirebase() method return an empty list and Setting Singleton property value in Firebase Listener.

The tl;dr is: any code that needs data from the database, needs to be inside onDataChange or be called from there.

The simplest way for you to do that with your code, is to move the second listener into the onDataChange for the first one, and then do the final sum in the inner onDataChange:

query1.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        for (DataSnapshot d : snapshot.getChildren()) {
            Gelirler gelirler = d.getValue(Gelirler.class);
            gelirler.setGelirid(d.getKey());
            toplamgelir = +gelirler.getGelirTutar();
        }
        TVbugungeliristoc.setText(String.valueOf(toplamgelir) + " TL");

        Query query2 = myRef2.orderByChild("giderZaman").startAt(getStartOfDay(today).getTime()).endAt(getEndOfDay(today).getTime());
        query2.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                for (DataSnapshot d : snapshot.getChildren()) {
                    Giderler giderler = d.getValue(Giderler.class);
                    giderler.setGiderid(d.getKey());
                    toplamgider = +giderler.getGiderTutar();
                }
                TVbugungideristoc.setText(String.valueOf(toplamgider) + " TL");

                double result = (toplamgelir-toplamgider);
                TVbugunKarZararistoc.setText(String.valueOf(result));
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                throw error.toException(); // never ignore errors
            }
        });

    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {
        throw error.toException(); // never ignore errors
    }
});

A new alternative is to use the new get() method, instead of addListenerForSingleValueEvent. That returns a Task object, so you can then use Tasks.whenAll(...) to wait for all of them to be done.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • thank you so so much mr Frank :) i am really happy that finally i solved my problem with your help. maybe one day if you travel to istanbul i will order cup of coffee with love :) – anasdmr Feb 19 '21 at 20:30
  • 1
    Good to hear you got it working @anasdmr And Turkish coffee sounds lovely. ☕️ – Frank van Puffelen Feb 19 '21 at 21:12