0

I'm having an issue with 2 separate methods, essentially the same issue where the database reference is firing and retrieving all the correct paths from the relevant nodes, but skips over the first fire on onDataChange then fires as expected afterwards giving the values needed.

The general context of these 2 methods is retrieving the value at the database reference using a code/value (specified path) to get to its relevant value. This value is retrieved and used elsewhere in the program.

I've looked at many problems regarding onDataChange not firing. Solved many of those issues elsewhere in my program but somehow these 2 methods are persisting with this issue. Ive run debug multiple times and dont understand how its showing and getting the correct paths but skips the first run on onDataChange where other methods implementing the exact same principle is running perfecting.

Im only posting the first issue


in onCreate

databaseReference_AUTH_TABLE = FirebaseDatabase.getInstance().getReference(AUTH_TABLE_TAG); verified = false;

Context is im using a dialog to authenticate a code. Check if the code exists in the database. And if so have the rest of the program run what i need it to do

public void authenticateProductID(final String code){
    databaseReference_AUTH_TABLE.child(code).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if(dataSnapshot.exists() && !verified){//Exists and is not verified yet
                PID = dataSnapshot.getValue().toString();
                verified = true;
                return;
            }
        }

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

        }
    });
}

public void showPopupProduct_btn(View view){
    final Dialog dialogProductVerification = new Dialog(this);
    dialogProductVerification.setContentView(R.layout.layout_popup_product);

    Button authenticate = dialogProductVerification.findViewById(R.id.btnPopupProductVerification);

    authenticate.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            EditText verificationCode = dialogProductVerification.findViewById(R.id.editTextPopupCode);
            code = verificationCode.getText().toString();
            if(noDuplicateCode(code)){
                authenticateProductID(code);
                if(verified){
                    getPackage(PID, code);
                    txtResult.setText(code);
                }
                else{
                    Toast.makeText(POSActivity.this, "Authentication Failed", Toast.LENGTH_SHORT).show();
                }
            }


        }
    });
    dialogProductVerification.show();

}

Because onDataChange isn't fired the first time, verified is false. But 2nd button click everything is perfect.

firbase node

Basically my app will be finished when this is resolved. Any help will be much appreciated. Thank you in advance

Ty Xonox
  • 3
  • 1

1 Answers1

0

Firebase APIs are asynchronous, which means that the onDataChange() method 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. So 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 verified boolean that you are trying to use, is not populated from the callback yet. So simply creating it as a global variable won't help you at all.

Basically, you're trying to use a value 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 move the code that queries the second node inside the first callback (inside the onDataChange() method) so-called nested queries, 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
  • Thank you! Watch the video and used the custom callback and tweaked it the way I needed it. Put if(verified)... in the onCallback in the onClickListener. Everything is working 100s now. – Ty Xonox Feb 08 '19 at 13:28