Q:

Informing the user if a Firebase search was successful

I'm writing a static method for a program I've been working on to go through the entries in the "graylist" in my Firebase database and check against user input to see if that entry exists. I'm able to locate the entry just fine, but because of some constraints of the way the threads work when reading/writing data from/to Firebase, I'm unable to figure out how to inform the user if the operation was successful or not.
I have the following method:
public static void addUser() {
    final boolean [] complete = new boolean[1];
    final String email = Tools.getEmail();
    DatabaseReference grayRef = FirebaseDatabase.getInstance().getReference().child("graylist");

    // Search the graylist for the email specified.
    CountDownLatch latch = new CountDownLatch(1); // need this so Parse-Ly doesn't close before event fires
    grayRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onCancelled(DatabaseError dbe) {}

        @Override
        public void onDataChange(DataSnapshot snap) {
            Iterable<DataSnapshot> graylist = snap.getChildren();
            for(DataSnapshot gray : graylist) {
                String uid = gray.getKey();
                String em = gray.getValue(String.class);
                if(em.equals(email)) {
                    // We found the one we're looking for. Insert its UID into the whitelist.
                    DatabaseReference whiteRef = FirebaseDatabase.getInstance().getReference().child("whitelist");
                    whiteRef.child(uid).setValue(email, new DatabaseReference.CompletionListener() {
                        @Override
                        public void onComplete(DatabaseError dbe, DatabaseReference dbr) {
                            complete[0] = true;
                            latch.countDown();
                            if(dbe != null) {
                                System.err.println("Error adding user to whitelist!");
                                dbe.toException().printStackTrace();
                            }
                        }
                    });
                    break;
                }
            }
            if(latch.getCount() > 0) {
                complete[0] = false;
                latch.countDown();
            }
        }
    });

    try {
        latch.await(); // wait for event to fire before we move on
    } catch(InterruptedException ie) {
        System.err.println("ERROR: Add user latch interrupted!");
        ie.printStackTrace();
    }

    if(complete[0]) ParselyMain.createAlert(AlertType.CONFIRMATION, "User Added", "User added to the whitelist!");
    else ParselyMain.createAlert(AlertType.INFORMATION, "User Not Found", "That user was not found in the graylist!");
}

I realize how hacky the final boolean array is, but even that is not working for me. The idea was to use a CountDownLatch and only count down when the write is successful. If all entries from the graylist are read and the CountDownLatch is still at 1, then nothing has been written, and it should count down to exit the thread, but the boolean would determine if the operation is successful or not.
The problem is that it seems to reach the if block after my for loop before the onComplete method is called, resulting in it thinking the operation failed (even though my database on Firebase shows otherwise), and the wrong alert is output.
Can anyone think of a better way to handle this so that I can properly inform them if the user was added to the whitelist or if the user was not found?

A:

Operations on the Firebase database are asynchronous by nature, so even if somehow you make the above code work, eventually you'll run into more complex cases where much of the lines of code are doing synchronization instead of handling the functionality of your application. This would lead to unmaintainable code that is easy to break.
So the simplest and "natural" way of processing the database request is to handle each event in the code whenever it occurs. This means informing the user of a successful update when the onComplete method is invoked, and informing the user of a failure when all the children entities have been checked and no match was found:
public static void addUser() {
    final String email = Tools.getEmail();
    DatabaseReference grayRef = FirebaseDatabase.getInstance().getReference().child("graylist");

    // Search the graylist for the email specified.
    grayRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onCancelled(DatabaseError dbe) {}

        @Override
        public void onDataChange(DataSnapshot snap) {
            boolean found = false;
            Iterable<DataSnapshot> graylist = snap.getChildren();
            for(DataSnapshot gray : graylist) {
                String uid = gray.getKey();
                String em = gray.getValue(String.class);
                if(em.equals(email)) {
                    found = true;
                    // We found the one we're looking for. Insert its UID into the whitelist.
                    DatabaseReference whiteRef = FirebaseDatabase.getInstance().getReference().child("whitelist");
                    whiteRef.child(uid).setValue(email, new DatabaseReference.CompletionListener() {
                        @Override
                        public void onComplete(DatabaseError dbe, DatabaseReference dbr) {
                            complete[0] = true;
                            if(dbe != null) {
                                System.err.println("Error adding user to whitelist!");
                                dbe.toException().printStackTrace();
                            } else {
                                Platform.runLater(() -> {                                  
                                    ParselyMain.createAlert(AlertType.CONFIRMATION, "User Added", "User added to the whitelist!");
                                });
                            }
                        }
                    });
                    break;
                }
            }
            if(!found) {
                Platform.runLater(() -> {
                    ParselyMain.createAlert(AlertType.INFORMATION, "User Not Found", "That user was not found in the graylist!");
                });
            }
        }
    });
}

