0

I'm currently developing an Android app that deals with storing book translations. I'm using Firebase to hold all the data online, and I have no trouble pulling data from it and storing them as Book objects. I have a master list of books in the main class that stores all the books from the Firebase database, however the list doesn't seem to update properly.

public static List<Book> books = new ArrayList<Book>();

protected void onCreate(Bundle savedInstanceState) {
    myFirebaseRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            for (DataSnapshot bookSnapshhot : snapshot.getChildren()) {
                Book book = bookSnapshhot.getValue(Book.class);
                books.add(book);
                System.out.println(book.getAuthor() + " - " + book.getTitle());
                for (Chapter chapter : book.getChapters()) {
                    System.out.println(chapter.getTitle());
                }
                for (Genre genre : book.getGenres()) {
                    System.out.println(genre.getGenre());
                }
                System.out.println(books.size());
            }
        }
        @Override public void onCancelled(FirebaseError error) { }
    });
    System.out.println(books.size());
}

In that body, the size of books is correct (right now it is only 1). However if I call the same print statement outside of that code body (the last line), it gives me 0. I don't know why, because it successfully adds it inside the onDataChange() method but it seems to not apply the changes on the outside.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Ed Wu
  • 107
  • 2
  • 2
  • 8
  • Shadab's answer explains it: you cannot return something now that hasn't loaded yet. You might also want to read my answer here: http://stackoverflow.com/questions/33203379/setting-singleton-property-value-in-firebase-listener. It uses a few more words to explain it (albeit in a different context: writing data). – Frank van Puffelen May 04 '16 at 20:33

2 Answers2

2

I think that your problem is about the asyncronously of the ValueEventListener.

The onDataChange is called asynconously.

You have to use the books after the onDataChange is called.

spassador
  • 393
  • 1
  • 12
2

The addValueEventListener() will fetch the data from Firebase asynchronously. What your code depicts is that you are adding ValueEventListener and then printing System.out.println(books.size());. This means your logs gets displayed after you add ValueEventListener(which doesn't means your listener gets invoked). At this point your listener is not invoked yet and so isn't onDataChange(). Thus you won't ever get updated count outside the listener scope.

Shadab Ansari
  • 7,022
  • 2
  • 27
  • 45