2014-12-16 5 views
3

Когда я вызываю listPost(), он возвращает NULL. Думаю, он не дождался, когда слушатель получит сообщение от firebase. Как я могу подождать, чтобы получить сообщение от firebase до возвращения arrayPost?Извлечение данных из возвратной базы базы данных NULL

public Post[] listPost() { 
    ArrayList<Post> list = new ArrayList<Post>(); 

    // Fetch post from firebase 
    postRef.addValueEventListener(new ValueEventListener() { 

     @Override 
     public void onDataChange(DataSnapshot snapshot) { 
      for(DataSnapshot child : snapshot.getChildren()) { 
       String id = child.getKey(); 
       String title = child.child("title").getValue().toString(); 
       String content = child.child("content").getValue().toString(); 
       String date = child.child("date").getValue().toString(); 
       String status = child.child("status").getValue().toString(); 

       Post post = new Post(); 
       post.setId(id); 
       post.setTitle(title); 
       post.setContent(content); 
       post.setDate(date); 
       post.setStatus(status); 
       list.add(post); 
      } 
     } 

     @Override 
     public void onCancelled(FirebaseError error) { 
      System.out.println("The read failed: " + error.getMessage()); 
     } 
    }); 

    // Convert ArrayList to Array 
    Post[] arrayPost = new Post[list.size()]; 
    list.toArray(arrayPost); 
    return arrayPost; 
} 
+1

В общем случае (это не относится к Firebase) вы можете просто дождаться окончания операции, используя некоторую комбинацию методов 'Object.wait' и' Object.notify' Java. Я не могу быстро найти хороший пример прямо сейчас, поэтому надеюсь, что этого достаточно, чтобы вы начали, пока кто-то не даст ответ. –

+0

Привет! Пожалуйста, прочитайте руководство по Java/Android (https://www.firebase.com/docs/android/guide/), которое охватывает основные 101 основы, такие как чтение данных и использование обратных вызовов событий. – Kato

ответ

3

В то время как вы можете, конечно, превратить listPost() в синхронном методе используя что-то вроде семафоров, это не путь Firebase предназначен для работы. Например, каждый раз, когда вы вызываете addValueEventListener(), он будет добавлять нового слушателя, который будет вызываться всякий раз, когда ваши данные меняются один раз за каждый раз, когда вы вызываете listPost().

Если целью метода listPost() является обновление некоторого состояния где-то (например, ваш пользовательский интерфейс), вы можете вместо этого обновить состояние непосредственно из вашего метода onDataChanged(). Это гарантирует, что вы добавите только один прослушиватель событий значения, и обновления в ваших данных всегда будут отображаться в вашем текущем состоянии без необходимости обновления.

// Setup once when your app loads 
postRef.addValueEventListener(new ValueEventListener() { 

    @Override 
    public void onDataChange(DataSnapshot snapshot) { 
     ArrayList<Post> list = new ArrayList<Post>(); 
     for(DataSnapshot child : snapshot.getChildren()) { 
      String id = child.getKey(); 
      String title = child.child("title").getValue().toString(); 
      String content = child.child("content").getValue().toString(); 
      String date = child.child("date").getValue().toString(); 
      String status = child.child("status").getValue().toString(); 

      Post post = new Post(); 
      post.setId(id); 
      post.setTitle(title); 
      post.setContent(content); 
      post.setDate(date); 
      post.setStatus(status); 
      list.add(post); 
     } 
     // Do something with your list of posts here 
     updateSomething(list); 
    } 

    @Override 
    public void onCancelled(FirebaseError error) { 
     System.out.println("The read failed: " + error.getMessage()); 
    } 
}); 

Поскольку у вас есть список детей здесь вы также можете использовать ChildEventListener здесь вместо того, чтобы и реагировать на ребенок добавил, ребенок изменился и ребенок удалены события, чтобы обновить состояние или пользовательский интерфейс.

Смежные вопросы