0

On QuotesRepository, wherein I fetch the data from Firestore db works fine on line 21, while when I try to access the data on line 22 after setting the value:

I tried to see if the data is assigned on qouteList.

the data is null or has no object in reference. It seems that the data is not being updated on line 22.

I also noticed that when the listener became in active after fetching data

21: Log.d("tag", "Repository: Quotes: " + qoutes.toString());

    D/tag: Repository: Quotes: [Qoutes{author='almazan', quoted='"content"'}, Qoutes{author='_new Author', quoted='_new Content'}, Qoutes{author='Albert Camus', quoted='“The truth is that everyone is bored, and devotes himself to cultivating habits.”'}]

22: qoutesList = qoutes;

25: Log.d("tag", "Repository: QuoteList: " + qoutesList.toString());

    Repository: QuoteList: []

Firestore Database

The classes:

public class Qoutes {
    String author;
    String quoted;

    public Qoutes() {
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getQuoted() {
        return quoted;
    }

    public void setQuoted(String quoted) {
        this.quoted = quoted;
    }

    @Override
    public String toString() {
        return "Qoutes{" +
                "author='" + author + '\'' +
                ", quoted='" + quoted + '\'' +
                '}';
    }
}
public class QoutesRepository {

    FirebaseFirestore firebaseFirestore;
    List<Qoutes> qoutesList;

    public QoutesRepository() {
        this.firebaseFirestore = FirebaseFirestore.getInstance();
        qoutesList = new ArrayList<>();
    }

    public List<Qoutes> getQoutesList() {
        firebaseFirestore.collection("quotes").addSnapshotListener(new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
                List<Qoutes> qoutes = new ArrayList<>();
                assert value != null;
                for (QueryDocumentSnapshot documentSnapshot : value) {
                    if (documentSnapshot != null)
                        qoutes.add(documentSnapshot.toObject(Qoutes.class));
                }
                Log.d("tag", "Repository: Quotes: " + qoutes.toString());
                qoutesList = qoutes;
            }
        });
        Log.d("tag", "Repository: QuoteList: " + qoutesList.toString());
        return qoutesList;
    }

I tried to change all the document in a collection fetcher from firebase documentation same problem

            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {

                List<Qoutes> qoutes = new ArrayList<>();

                if (task.isSuccessful()) {
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        qoutes.add(document.toObject(Qoutes.class));
                        Log.d("tag", document.getId() + " => " + document.getData());
                    }
                } else {
                    Log.d("tag", "Error getting documents: ", task.getException());
                }
                qoutesList.addAll(qoutes);
            }
        });

How do I assign or pass the fetched data from Firestore into global var: List<Quotes> quoteList, without a null pointer exception?

  • The problem is not so much that the `quoteList` is global, but that you try to access it before `onEvent` has ever run. I recommend setting breakpoints on those lines and then running the code in a debugger, to see that they get executed in a different order from what you expect. The solution is always the same: any code that needs the data from the database, has to be *inside* the `onEvent`, be called from there, or otherwise synchronized. – Frank van Puffelen Nov 20 '22 at 15:06
  • Have Read: get-contacts-from-firebase-method-return-an-empty-list - Found out that firebase returns asynchronously, making data return later. He suggested using `ondatachange` method, which is not found in Firestore. Cannot use `onDataChange` method – Gilbert Almazan Nov 21 '22 at 03:32
  • In addition, it was suggested to use a callback function instead, and I don't quite understand using a callback function to make the code run synchronous. – Gilbert Almazan Nov 21 '22 at 03:42
  • `onEvent` methods such as onSuccess on Failure methods in a listener? I need to load the data synchronously and pass it on a countdown timer class to display the loaded data. It works fine If the getQouteList method is directly coded on the fragment where I am using the data, which makes it more messy and cluttered. So I tried to follow MVVM in saving and loading data. – Gilbert Almazan Nov 21 '22 at 03:49
  • 1) The equivalent of `onDataChange` in that answer is `onEvent` in your code. 2) There is no way to make asynchronous code synchronous. To understand how a callback works, look at `EventListener` in your code. That's also a callback. 3) See #2: there is no way to make asynchronous code synchronous, nor is there a need. – Frank van Puffelen Nov 21 '22 at 04:12
  • Still not working with `onEvent` because the document data load asynchronously. With `onEvent` method - is there a way to make it wait for the result before passing it? – Gilbert Almazan Nov 21 '22 at 06:18
  • 1
    There is no way you can do that. Firebase API is asynchronous. So please check the duplicate answers. You might also be interested in reading this [resource](https://medium.com/firebase-tips-tricks/how-to-read-data-from-cloud-firestore-using-get-bf03b6ee4953). – Alex Mamo Nov 21 '22 at 09:10

0 Answers0