1

I'm trying to get a value and then increase that value by one. The problem is I cannot get this value out of onDataChange method, if I do the job inside the method I get loop and it continuously adding ones to this value. What should I do?

Here is my code:

rootRef.child("users").addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    int rat = Integer.parseInt(dataSnapshot.child(current_user).child("rating").getValue().toString());

                    System.out.println(rat);

                    rat = rat + 1;

                    rootRef.child("users").child(current_user).child("rating").setValue(rat);

                    System.out.println(rat);
                }

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

                }
            });
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
tsogam
  • 51
  • 1
  • 12

2 Answers2

5

If you need to receive data one time from firebase db then you need to use addListenerForSingleValueEvent(...) instead of addValueEventListener(...). Then onDataChange() will return only one time.

addValueEventListener will call on each time when there is any value update.

Here in the above situation each time when you increment the values and update the node again addValueEventListener is called repeatedly , thus it behave like infinite loop.

William Reed
  • 1,717
  • 1
  • 17
  • 30
Basil jose
  • 774
  • 3
  • 11
  • That is exactly what I was looking for. Thanks. – tsogam Aug 01 '18 at 14:39
  • happy to help you – Basil jose Aug 01 '18 at 15:06
  • @Ts.Gams This answer doesn't solve "I cannot get this value out of onDataChange method" at all but good to hear that it solved your problem :) – Alex Mamo Aug 01 '18 at 15:07
  • @AlexMamo My aim was to increase the value and I had two choices: somehow increase the value inside the method or take the value out of the method and then change it. The problem was that it wasn't working inside the method and I didn't know if I was able to take the value from the method. Using the second method was the better choice in this case. But your answer was also helpful and I'll consider it next time. Thanks anyways. – tsogam Aug 01 '18 at 15:44
1

Firebase APIs are asynchronous, meaning that the onDataChange() method that you are talking about returns immediately after it's invoked and the callback from the Task it returns, will be called some time later. There are no guarantees about how long it will take, it may take from a few hundred milliseconds to a few seconds before that data is available. Because that method returns immediately, the value of your rat variable you're trying to use it outside the onDataChange() method, will not have been populated from the callback yet.

Basically, you're trying to return the value of rat synchronously from an API that's asynchronous. That's not a good idea. You should handle the APIs asynchronously as intended.

A quick solve for this problem would be to use the value rat only inside the onDataChange() method, otherwise I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193