Firebase数据库获取节点值

时间:2016-11-12 15:16:12

标签: java android firebase listener countdownlatch

我想从我的Firebase RealTime数据库获取wgID,它的值为/ WG / FlatNumber / 现在这是我的代码:

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;

所以,当我不使用CountdownLatch时,System.out.println会给我这个:

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

所以我看到它,在方法准备就绪后执行了Listener。

如果我使用CountDownLatch,它只会运行直到它来到" cdl.await()"然后停止,监听器永远不会执行,应用程序停止。

那么如何获取我的ID,我的意思是我只想从我的数据库中获取一个值,您可以使用" setValue()"但你不能用" getValue"或其他什么,它必须由听众完成?

1 个答案:

答案 0 :(得分:0)

该问题是由于两个事实造成的:

  1. \11\在主线程上运行,阻止它直到通知。
  2. Firebase回调也有望在主线程上发生。

由于cdl.await()发生在数据库回调之前,所以它将无限期地阻塞主线程,从而防止了回调的发生(因为它已排队等待在无限期阻塞的主线程上运行)。

解决方案是根本不使用CountDownLatch。 Firebase API都是异步的,调用者应期望在主线程上执行查询后结果会到达。执行应该从该回调继续,而不是从等待闩锁的地方继续。