1

I want to get my wgID from my Firebase RealTime Database, it is located as a value of /WG/FlatNumber/ Now here is my Code:

MainActivity:

System.out.println("1");
dbContact.schreibeFlatObjekt();
System.out.println("7");

schreibeFlatObjekt:

//wgID is global
private String wgID;
public schreibeFlatObjekt(){
//CountDownLatch to wait for the Listener
final CountDownLatch cdl = new CountDownLatch(1);


    ValueEventListener listener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            System.out.println("3");
            //Getting the Data from the snapshot
            wgID = (String) dataSnapshot.getValue();
            System.out.println("4 wgID: " + wgID);
            //counting down the cdl so the cdl.await() can go on 
            cdl.countDown();

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };

    System.out.println("2");
    fref.child("WG").child("FlatNumber").addListenerForSingleValueEvent(listener);
    System.out.println("5");

    try{
        cdl.await();
    }
    catch(Exception e)
    {
        System.out.println(e.toString());
    }
    System.out.println("6 wgID: " +wgID);
    return 0;

So when I don't use the CountdownLatch, the System.out.println give me this:

I/System.out: 1
I/System.out: 2
I/System.out: 5
I/System.out: 6 wgID: null
I/System.out: 7
I/System.out: 3
I/System.out: 4 wgID: 1

So as I see it, the Listener is executed, after the method is already ready.

If I use the CountDownLatch, it only runs until it comes to "cdl.await()" and then just stops, the Listener is never executed and the app stops.

So how do I get my ID, I mean I just want one Value from my Database, you can set it with "setValue()" but you cannot read it with "getValue" or something, it has to be done with listeners?

madhan kumar
  • 1,560
  • 2
  • 26
  • 36
jochot
  • 167
  • 1
  • 13

1 Answers1

0

The problem is due to two facts:

  1. cdl.await() runs on the main thread, blocks it until notified.
  2. The Firebase callback also expects to happen on the main thread.

Since cdl.await() happens before the database callback, it blocks the the main thread indefinitely, which prevents the callback from happening (since it's queued up to run on the main thread, which is blocked indefinitely).

The solution is not to use a CountDownLatch at all here at all. Firebase APIs are all asynchronous, and the caller should expect that the result arrives after the query is performed on the main thread. Execution should continue from that callback, not from something waiting on a latch.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441