0

I am setting up a debit card screen where you can add your debit/credit card to your account. I have it set up all nice and dandy, but my issue comes with checking whether the card input is a duplicate or not.

The code is functioning, but the part where the card is added to the account happens before the card is flagged as a duplicate, and I am not sure why this is happening.

Here is the code that calls my checkDuplicate() method and then proceeds to add the card to the account if everything is valid

        buy.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            checkDuplicates(cardForm.getCardNumber());
            if(!isDuplicate) {
            if (cardForm.isValid()) {
                alertBuilder = new AlertDialog.Builder(AddDebits.this);
                alertBuilder.setTitle("Please ensure your card information is correct");
                alertBuilder.setMessage("Card number: " + cardForm.getCardNumber() + "\n" +
                        "Card expiry date: " + cardForm.getExpirationDateEditText().getText().toString() + "\n" +
                        "Card CVV: " + cardForm.getCvv() + "\n" +
                        "Postal code: " + cardForm.getPostalCode() + "\n" +
                        "Name: " + cardForm.getCardholderName());
                alertBuilder.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        final CreateCard newCard = new CreateCard(cardForm.getCardholderName(), cardForm.getCardNumber(),
                                cardForm.getExpirationDateEditText().getText().toString(), cardForm.getCvv(), cardForm.getPostalCode());

                        amountOfCards(new AmountOfCardsCallback() {
                            @Override
                            public void onCallback(long amount, long defaultCard) {
                                userRef.child("amountOfCards").setValue(++amount);
                                userRef.child("Card" + amount).setValue(newCard);
                            }
                        });

                        dialogInterface.dismiss();
                        Toast.makeText(AddDebits.this, "Your card has been added to your account", Toast.LENGTH_LONG).show();
                    }
                });
                alertBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.dismiss();
                    }
                });

The snippet of this I am most concerned about is the first few lines

    public void onClick(View view) {
    checkDuplicates(cardForm.getCardNumber());
    if(!isDuplicate) {
    if (cardForm.isValid()) {

The checkDuplicate() method is shown below

    private void checkDuplicates(final String cardNumber)
{
    userRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(final DataSnapshot dataSnapshot) {
            amountOfCards(new AmountOfCardsCallback() {
                @Override
                public void onCallback(long amount, long defaultCard) {
                    for(int i = 0; i < amount; i++) {
                        if (dataSnapshot.child("Card" + i).child("cardNumber").getValue() != null) {
                            if (dataSnapshot.child("Card" + i).child("cardNumber").getValue().toString().equals(cardNumber)) {
                                isDuplicate = true;
                                alertBuilder.setTitle("Duplicate Card")
                                        .setMessage("You already have this card saved");
                                alertBuilder.show();

                                alertBuilder.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {

                                    }

                                });

                            }
                        }
                    }
                }
            });
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

This method functions perfectly fine. It finds the duplicates and displays a dialog box when this happens. But the issue is it does not happen until after the card is added to the account.

So the if(cardForm.isValid()) code happens before the duplicate is flagged.

Why could this be happening?

brent_mb
  • 337
  • 1
  • 2
  • 14

1 Answers1

2

The issue appears to be the fact that you are checking for duplicates in a callback onDataChange

which takes a moment to get called. In the meantime, your if(!isDuplicate) is called and executed since onDataChange hasn't changed isDuplicate to false yet.

This javascript example has a similar issue, and the recommedation is to do all logic dependent on the callback within the callback method itself. In this case you would need to rework your code to put all necessary code inside if(!isDuplicate) into your onDataChange() found within the checkDuplicate()

Chris DL
  • 91
  • 7
  • Thanks for the response! Unfortunately, since I am retrieving data from my `firebase-realtime-database` I cannot make the `checkDuplicates` method a Boolean as it cannot return a value. I also only have called `checkDuplicates()` one time in my project – brent_mb Feb 26 '19 at 17:52
  • Searched a bit and found [this](https://stackoverflow.com/questions/5010288/how-to-make-a-function-wait-until-a-callback-has-been-called-using-node-js), its a JS question, but the general idea may work for you. That is, in your onDataChange() method, insert your other logic for continuing through your program. – Chris DL Feb 26 '19 at 18:19
  • @brent_mb Updated my answer – Chris DL Feb 26 '19 at 18:32
  • Thanks! I combined the code into my `onDataChange` in my `checkDuplicates()` method and it works perfectly now. – brent_mb Feb 26 '19 at 18:42