0

Using Firebase Database. I have a database which stores the registration information for patients. While registering a new patient, i'm checking whether the person is already registered or not.

The function below checks if a registration for that person is already made or not. I'm checking this by going to "Users/Phone_no/Patient_name". If the DataSnapshot is not null registration is already there.

private boolean checkAlreadyRegistered(){

    final boolean[] alreadyRegistered = {false};
    /*Get the reference*/
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users/" + childDetails.getPhone() + "/" + childDetails.getPatientName());
    mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.d(TAG, "onDataChange: " + dataSnapshot);
            if (dataSnapshot.getValue() != null) {

                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setTitle("Record Already Exists");
                builder.setMessage("The current patient is already registered");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {

                        alreadyRegistered[0] = true;
                    }
                });
                builder.create();
                builder.show();
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

            Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_LONG).show();
        }
    });
    return  alreadyRegistered[0];
}

From saveInDatabase i'm calling the above function

void saveInDatabase(Long patient_id) {


    boolean alreadyRegistered = checkAlreadyRegistered();
    if (alreadyRegistered) {
        resetRegisterFields();
        return;
    }
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Current_registered_users");
    mDatabaseReference.setValue(patient_id + 1);
    childDetails.setPatient_id(patient_id);
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users");
    Log.d(TAG, "saveInDatabase: "+mDatabaseReference);
    mDatabaseReference.child(childDetails.getPhone()).child(childDetails.getPatientName()).child("Registration Details").setValue(childDetails);
    Button bt = (Button) getView().findViewById(R.id.buttonRegister);
    resetRegisterFields();
    progressDialog.dismiss();
    displayPid(patient_id);
    bt.setEnabled(true);
    .
    .
}

What i want to do- Check if a registration based on phone_no/Patient_name is already made or not, if not save the details.

Problem - When a new registration is made it is added to the database, but after that the message "..Already registered", from checkAlreadyRegistered() ->onDataChange is displayed.

Why is that message coming, and how solve it?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
string24
  • 15
  • 6
  • `onDataChange()` fires asynchronously. `checkAlreadyRegistered()` returns before the result is available. See this answer for a detailed explanation: http://stackoverflow.com/a/41409942/4815718 – Bob Snyder Jan 23 '17 at 18:28
  • So, calling saveInDatabase() from onDataChange() will solve the problem, right? – string24 Jan 23 '17 at 18:33

2 Answers2

0

All data reading in Firebase happens asynchronously, so I recommend you change your code to something that looks like this:

private void checkAlreadyRegistered(){

    /*Get the reference*/
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users/" + childDetails.getPhone() + "/" + childDetails.getPatientName());
    mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.d(TAG, "onDataChange: " + dataSnapshot);
            if (dataSnapshot.getValue() != null) {

                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setTitle("Record Already Exists");
                builder.setMessage("The current patient is already registered");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        resetRegisterFields();
                    }
                });
                builder.create();
                builder.show();
            }
            else
            {
                saveInDatabase(patient_id); //TODO change this accordingly
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

            Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_LONG).show();
        }
    });
}

And your save method:

void saveInDatabase(Long patient_id) {
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Current_registered_users");
    mDatabaseReference.setValue(patient_id + 1);
    childDetails.setPatient_id(patient_id);
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users");
    Log.d(TAG, "saveInDatabase: "+mDatabaseReference);
    mDatabaseReference.child(childDetails.getPhone()).child(childDetails.getPatientName()).child("Registration Details").setValue(childDetails);
    Button bt = (Button) getView().findViewById(R.id.buttonRegister);
    resetRegisterFields();
    progressDialog.dismiss();
    displayPid(patient_id);
    bt.setEnabled(true);
    .
    .
}
0

You have to wait for the response from Firebase. You can add a Callback to run the rest of your code once it's been retrieved. Do something like this:

Create an interface called ServerCallback:

public interface ServerCallback
{
    void onSuccess(boolean result);
}

In your checkAlreadyRegistered() method, add the callback so it runs once the data is retrieved from Firebase:

private void checkAlreadyRegistered(final ServerCallback callback){
    final boolean[] alreadyRegistered = {false};
    /*Get the reference*/
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users/" + childDetails.getPhone() + "/" + childDetails.getPatientName());
    mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.d(TAG, "onDataChange: " + dataSnapshot);
            if (dataSnapshot.getValue() != null) {
                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setTitle("Record Already Exists");
                builder.setMessage("The current patient is already registered");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {

                        alreadyRegistered[0] = true;
                        callback.onSuccess(alreadyRegistered[0]);
                    }
                });
                builder.create();
                builder.show();
            }
            else
               callback.onSuccess(alreadyRegistered[0]);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_LONG).show();
        }
    });
}

Then in your saveInDatabase(), wait for the callback, then run the rest of your code:

void saveInDatabase(Long patient_id) {
    boolean alreadyRegistered = checkAlreadyRegistered(new ServerCallback() {
        @Override
        public void onSuccess(boolean result)
        {
            if (alreadyRegistered) {
                resetRegisterFields();
                return;
            }
            mDatabaseReference = FirebaseDatabase.getInstance().getReference("Current_registered_users");
            mDatabaseReference.setValue(patient_id + 1);
            childDetails.setPatient_id(patient_id);
            mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users");
            Log.d(TAG, "saveInDatabase: "+mDatabaseReference);
            mDatabaseReference.child(childDetails.getPhone()).child(childDetails.getPatientName()).child("Registration Details").setValue(childDetails);
            Button bt = (Button) getView().findViewById(R.id.buttonRegister);
            resetRegisterFields();
            progressDialog.dismiss();
            displayPid(patient_id);
            bt.setEnabled(true);
            .
            .
        });
 }
Aubtin Samai
  • 1,281
  • 13
  • 24