0

tried retrieve data from firebase when user click the button, but the data not displayed if the button is click for the first time, then if i click again the data is displayed.. any idea what i should adding to the code so the data is appear on the first click attempt..

here are the code :

  btnprediksi.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

         efekGK(); 

        }
    });

here is the efekGK method

private void efekGK() {

    final DatabaseReference CekDataGK;
    posisi="GK";
    CekDataGK=FirebaseDatabase.getInstance().getReference();
    CekDataGK.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if (dataSnapshot.child("PlayerSkills").child(username).child("GK").exists()) {

                PlayersSkill playerData = dataSnapshot.child("PlayerSkills")
                        .child(username)
                        .child("GK")
                        .getValue(PlayersSkill.class);

                assert playerData != null;

                 String basGKform = playerData.getNumform();
                 String basGKExp=playerData.getNumexperience();
                 Toast.makeText(HomeActivity.this, basGKform, Toast.LENGTH_SHORT).show();


            } 
        }

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

        }
    });
}

i using Toast to check if data is available or not. the result is when i click button toast displayed nothing, but when i click again Toast displaying the data I expected...

EDIT : I follow Alexios suggestion and it's works perfectly if the variable display inside the "efekgk" method.. but if I put it outside the method it's display nothing again at first click.

first I define the variable outside the method

   public class HomeActivity extends AppCompatActivity {
   private String basGKform, basGKExp; 
    .....}

and i moved the result into new method called displaydata

   private void displaydata() {
     Toast.makeText(HomeActivity.this, basGKform, Toast.LENGTH_SHORT).show();
   }

Resulting none again in its first click

  • 1
    Did you [enable disk persistence](https://firebase.google.com/docs/database/android/offline-capabilities#section-disk-persistence) by any chance? If so, keep in mind that [disk persistence and `addListenerForSingleValueEvent` don't work well together](https://stackoverflow.com/questions/34486417/firebase-offline-capabilities-and-addlistenerforsinglevalueevent). – Frank van Puffelen Feb 02 '20 at 21:14

2 Answers2

0

That happens because the request is asynchronous. And when you click to display the firebase has not send you the data , and when you click again it displays beacuse you got data from the previous request.

I suggest to do it with callback

    public interface DataIsAvailable {
        public void onSuccess(DataSnapshot data);
    }

Trigger callback

private void efekGK(Final DataIsAvailable listener) {
    final DatabaseReference CekDataGK;
    posisi="GK";
    CekDataGK=FirebaseDatabase.getInstance().getReference();
    CekDataGK.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
               listener.onSuccess(dataSnapshot)

            } 
        }

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

        }
    });
}

And then at onClick

efekGK(new DataIsAvailable() {
        @Override
        public void onSuccess(DataSnapshot dataSnapshot) {

                PlayersSkill playerData = dataSnapshot.child("PlayerSkills")
                        .child(username)
                        .child("GK")
                        .getValue(PlayersSkill.class);

                assert playerData != null;

                 String basGKform = playerData.getNumform();
                 String basGKExp=playerData.getNumexperience();
                 Toast.makeText(HomeActivity.this, basGKform, Toast.LENGTH_SHORT).show();

        }

});

This should work.

Alexios
  • 358
  • 2
  • 8
  • it's work perfectly if the basGKForm and basGKExp it's display inside the method.., but if i define the variable of basGKform and basGKExp below public class and put Toast outside the efekGK(new ....) method is resulting blank Toast. – Aldin Džeko Feb 03 '20 at 09:39
0

It still displays nothing beacause is async , and it works ok with my suggestion because it is a callback when the data is ready. You have to do it with callback or if you know before you click what you want to query and it does not depends on what user does you can at the start of the activity to start the query with AsyncTask and when you are going to click the data will be ready .

Alexios
  • 358
  • 2
  • 8