New
New

Reputation: 9

Getting parent node through child node in Firebase Realtime database

In my app in Android studio I've coded for allowing users to book appointment with doctors. So if the doctor accepts the appointment, I want to change the value of child node "Status". For that I need the value of the parent node which is this .

For that I tried using String currentUserId = ds.getKey(); ,but ds,getKey() gives the value "Patient" which is a child node of the required parent node. So how do I get the key (circled red in image)?

patRef = database.getReference().child("Patient Appointments");

patRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (task.isSuccessful()) {
            for (DataSnapshot ds : task.getResult().getChildren()) {
                String pat = ds.child("Patient").getValue(String.class);

                if(pat.equals(Email)){
                    HashMap update= new HashMap();
                    update.put("Status","Appointment on "+date);

                    String currentUserId = ds.getKey();
                    Toast.makeText(DoctorNotification.this, currentUserId, Toast.LENGTH_SHORT).show();

                    patRef.child(currentUserId).updateChildren(update).addOnSuccessListener(new OnSuccessListener() {
                        @Override
                        public void onSuccess(Object o) {
                            Toast.makeText(DoctorNotification.this, "Appointment accepted", Toast.LENGTH_SHORT).show();
                        }
                    });

                    flag1="True";
                }

            }

            if(flag1.equals("False")){
                Toast.makeText(DoctorNotification.this, "Error", Toast.LENGTH_SHORT).show();

            }
        }

    }
});

Upvotes: 0

Views: 561

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

As you discovered yourself, you can update the current node in the loop with:

ds.getRef().child(currentUserId).updateChildren(update)

I wanted to provide an additional comment on the approach you take to finding the node to update. Right now you load all Patient Appointments to find one of them, which is going to be inefficient - especially one you start adding more appointment.

Use a query to only load the node for the current patient

One way to improve this is by using a query to only retrieve the appointment of the Patient you're looking for. That'd look something like this:

patRef = database.getReference().child("Patient Appointments");

Query patientQuery = patRef.orderByChild("Patient").equalTo(Email);

patientQuery.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    ...

And you can then remove the if(pat.equals(Email)){ from within the onComplete.

Use a query on both Patient and Status fields

One smaller optimization after this is that you probably only need to check the appointments that are pending. For that you'd like a query like above, but then on two fields.

This is not something the Firebase Realtime Database natively supports, but you can emulate it by adding a composite field to your data: "Patient_Status": "[email protected]_Pending". The query would then become:

patRef.orderByChild("Patient_Status").equalTo(Email+"_Pending");

Store the key of the node in your UI

The final improvement assumes that the doctor is actually shown a list of all (pending) appointments and then click to accept one or more of them. In such a scenario you already read all the appointments from the database to show them in the user interface.

If you store the key of each appointment in a (hidden) field in the user interface, you can then use that key when the doctor clicks it, and the entire update operation can become as simple as:

patRef
  .child("keyOfTheAppointmentTheDoctorClicked")
  .child("Status")
  .setValue("Appointment on "+date);

Upvotes: 1

Related Questions