2015-06-05 64 views
9

我想構建一個方法,返回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; 
} 

的問題是,該方法返回null這可能是因爲該方法不等到聽衆結束並返回null因爲它的message默認值。 如何使此方法等待,直到偵聽器發生,然後返回該值。

+0

假設root存儲在類中(並且類未被gc化)函數完成應該沒關係 –

+1

不能同步返回異步值。這裏的message變量是完全沒有意義的,因爲它不會在返回時被設置 - 數據必須先從服務器獲取。相反,getMessage()應該接受某種類型的回調或觸發事件。有[專門介紹這些概念的指南](https://www.firebase.com/docs/android/),充滿了例子和建議。 – Kato

+0

[使用此答案](http://stackoverflow.com/a/38542796/4882204)。我遇到了同樣的問題,並使用EventBus解決。 –

回答

2

不要使用Firebase作爲返回值的函數 - 它違背了它的異步性質。

計劃代碼結構允許Firebase執行它的任務,然後在關閉(塊)內轉到下一步。

例如,在您的代碼中,將函數更改爲不返回任何內容並在onDataChange內,因爲最後一行調用下一個函數來更新UI。

3

做一個接口

public interface OnGetDataListener { 
    //this is for callbacks 
    void onSuccess(DataSnapshot dataSnapshot); 
    void onStart(); 
    void onFailure(); 
} 

聲明以下函數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(); 
     } 
    }); 

} 

調用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"); 
       } 
      }); 

READDATA()裏面可以稱爲你的getMessage()方法,或者甚至在onCreate()內

+0

我按照這些說明點,我仍然遇到與OP完全相同的問題。我不明白我應該如何構建我的代碼,以便能夠使用Firebase數據庫中的數據 – Flaom