I'm working on a graphical program in Java (not Android) using Firebase where I'm trying to look through the values of one database for a certain string, and when I find it, take the data from that first database and write it to another database.
I'm able to correctly read and write the data, but I'm having issues with getting the program to terminate because of two specific problems.
If I do not "wait" for the completion listener somehow (in this case, a CountDownLatch), the program terminates before the onComplete() method of the completion listener has a chance to fire, and the value is never written to the database.
If I use a CountDownLatch to wait for the onComplete() method to fire, the program never terminates, because apparently the completion listener never fires.
When I do use the CountDownLatch, the data is written, but the completion listener never fires and the program does not terminate.
Here is the method in which I am doing this:
public static void addUser() {
final String email = Tools.getEmail();
DatabaseReference grayRef = FirebaseDatabase.getInstance().getReference().child("graylist");
// Search the graylist for the email specified.
CountDownLatch dataChange = 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.
final CountDownLatch completion = new CountDownLatch(1);
DatabaseReference whiteRef = FirebaseDatabase.getInstance().getReference().child("whitelist");
whiteRef.child(uid).setValue(email, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError dbe, DatabaseReference dbr) {
completion.countDown();
if(dbe != null) {
System.err.println("Error adding user to whitelist!");
dbe.toException().printStackTrace();
}
}
});
try {
completion.await();
System.out.println("User added successfully!");
} catch(InterruptedException ie) {
System.err.println("ERROR: Completion latch interrupted!");
ie.printStackTrace();
}
break;
}
}
dataChange.countDown();
}
});
try {
dataChange.await(); // wait for event to fire before we move on
} catch(InterruptedException ie) {
System.err.println("ERROR: Data change latch interrupted!");
ie.printStackTrace();
}
}
The "completion" CountDownLatch is the one I am using to wait on the onComplete() method to be triggered.
Does anyone have any insight as to why the completion listener never fires despite the data being written and appearing in the database?