等到firebase检索数据

ben*_*ben 18 java android listener firebase

我想构建一个返回child值的方法FireBase.我试着这样做:

public String getMessage(){

    root.child("MessagesOnLaunch").child("Message").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            message = (String) dataSnapshot.getValue();
            Log.i("4r398", "work");
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            Log.e("error", firebaseError.getMessage());
        }
    });
    return message;
}
Run Code Online (Sandbox Code Playgroud)

问题是该方法返回的null原因可能是因为该方法不会等到侦听器完成并返回,null因为它的默认值为message.如何使此方法等到侦听器发生然后返回值.

小智 9

建立一个界面

 public interface OnGetDataListener {
    //this is for callbacks
    void onSuccess(DataSnapshot dataSnapshot);
    void onStart();
    void onFailure();
}
Run Code Online (Sandbox Code Playgroud)

声明以下函数readData()

public void readData(Firebase ref, final OnGetDataListener listener) {
    listener.onStart();
    ref.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            listener.onSuccess(dataSnapshot);
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            listener.onFailure();
        }
    });

}
Run Code Online (Sandbox Code Playgroud)

调用readData()函数如下

readData(root.child("MessagesOnLaunch").child("Message"), new OnGetDataListener() {
                @Override
                public void onSuccess(DataSnapshot dataSnapshot) {

               //got data from database....now you can use the retrieved data


                }
                @Override
                public void onStart() {
                    //when starting
                    Log.d("ONSTART", "Started");
                }

                @Override
                public void onFailure() {
                    Log.d("onFailure", "Failed");
                }
            });
Run Code Online (Sandbox Code Playgroud)

readData()可以在你的getMessage()方法中调用,甚至可以在o​​nCreate()里面调用


Vla*_*kyi 6

不要将 Firebase 用作返回值的函数 - 这违背了它的异步性质。

规划允许 Firebase 执行其任务的代码结构,然后在闭包(块)内进入下一步。

例如,在您的代码中,将函数更改为不返回任何内容并在 onDataChange 中,因为最后一行调用 next 函数来更新您的 UI。

  • 这一切都很好,但在 Java 世界的其他部分,我们使用同步的 servlet 和 RestTemplates。谷歌引入异步库确实让事情变得复杂。 (2认同)
  • 这是标准方法,但在某些情况下这只会导致意大利面条式代码 (2认同)

小智 6

您可以使用CountDownLatch。这就是您可以使用它的方式。

public String getMessage(){
   CountDownLatch done = new CountDownLatch(1);
   final String message[] = {null}; 
   root.child("MessagesOnLaunch").child("Message").addListenerForSingleValueEvent(new ValueEventListener() {

    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        message[0] = (String) dataSnapshot.getValue();
        System.out.println("worked");
        done.countDown();
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {
        System.out.println("failed"+firebaseError.getMessage());
    }
});

try {
    done.await(); //it will wait till the response is received from firebase.
} catch(InterruptedException e) {
    e.printStackTrace();
}
return message[0];
}
Run Code Online (Sandbox Code Playgroud)

  • 很棒的方法!@Zod使用最终的AtomicReference或数组包装器g /设置消息 (3认同)