2015-06-05 17 views
9

Chcę zbudować metodę zwracającą wartość child w FireBase. Starałem się zrobić coś takiego:Poczekaj, aż baza danych uzyska dane

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; 
} 

Problem polega na tym, że metoda zwraca null To prawdopodobnie dlatego, że metoda nie czekać, aż zakończy się słuchaczem i powrócić null ponieważ jej wartość domyślną message. W jaki sposób sprawić, aby ta metoda była oczekiwana, dopóki słuchacz nie pojawi się , a następnie zwróci wartość.

+0

Zakładamy, że root jest przechowywany w klasie (a klasa nie jest w gc), nie powinno to mieć znaczenia, że ​​funkcja się zakończy –

+1

Nie można synchronicznie zwrócić wartości asynchronicznej. Zmienna "message" jest tutaj zupełnie bezsensowna, ponieważ nie będzie ustawiona w momencie, kiedy ją zwróci - dane muszą być najpierw pobrane z serwera. Zamiast tego funkcja getMessage() powinna albo zaakceptować wywołanie zwrotne, albo wywołać zdarzenie. Istnieje [przewodnik poświęcony tym pojęciom] (https://www.firebase.com/docs/android/), pełen przykładów i porad. – Kato

+0

[Użyj tej odpowiedzi] (http://stackoverflow.com/a/38542796/4882204). Mam do czynienia z tym samym problemem i rozwiązany przy użyciu EventBus. –

Odpowiedz

2

Nie używaj Bazy Firebase jako funkcji zwracających wartości - jest to sprzeczne z jej asynchroniczną naturą.

Struktura kodu planu, która pozwala Firebase wykonać to zadanie, a następnie w ramach zamknięcia (bloku) przejdź do następnego kroku.

W kodzie, na przykład, zmień funkcję, aby nie zwracać niczego i wewnątrz onDataChange, jak w ostatnim wierszu wywołaj następną funkcję, aby zaktualizować swój interfejs użytkownika.

3

Złóż interfejs

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

zadeklarować następującą funkcję 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(); 
     } 
    }); 

} 

Połącz się z ReadData() funkcję następująco

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() może być wywołana wewnątrz twoja metoda getMessage() lub nawet wewnątrz onCreate()

+0

Postępowałem zgodnie z tymi instrukcjami do kropki, a ja wciąż doświadczam dokładnie tego samego problemu co OP. Nie rozumiem, w jaki sposób mam uporządkować mój kod tak, aby móc korzystać z danych w bazie danych Firebase – Flaom

Powiązane problemy