java - Firebase 数据库获取节点值

标签 java android firebase listener countdownlatch

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

主要 Activity :

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

据我所知,监听器是在方法准备好之后执行的。

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

那么我如何获取我的ID,我的意思是我只想要数据库中的一个值,你可以用“setValue()”设置它,但你不能用“getValue”或其他东西读取它,它必须用监听器来完成?

最佳答案

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

  1. cdl.await() 在主线程上运行,阻塞它直到收到通知。
  2. Firebase 回调也预计在主线程上发生。

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

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

关于java - Firebase 数据库获取节点值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40564270/

相关文章:

Java 对象未返回预期数据

android - 为在 Libgdx android 中支持多个屏幕提供资源

java - 我可以在偏好设置中制作铃声吗

android - 我应该选择哪种应用程序间通信?

java - 未将图像 URL 字符串获取到 FirebaseDatabase

android - 错误:(66, 30)错误:PhoneAuthProvider包不存在

java - 在 Java 中对对象列表进行排序的最优雅的方法是什么?

java - 即使代码只执行一次,Intellij 断点也会停止执行两次

android - 如何将音频从 Firebase 加载到应用程序?

java - 将 Libgdx 滚动条添加到 TextArea