Reputation: 150
I'm trying to make a method that queries a list of projects from my Cloud Firestore database
. I would then set a RecyclerView
adapter with said list and it should display nicely. As of now, the RecyclerView
is empty. (I've also tested the RecyclerView
with dummy projects and they display just fine)
The projects list remains empty in the end of my method. Logs show up in a weird order (last log displays before the other logs). The logs order make me suspect that there's some separate thread/s running in the listener. I'm not exactly sure how to synchronize them.
private List<Project> projects;
private FirebaseFirestore db;
... In onCreateView() (i'm working in a fragment):
db = FirebaseFirestore.getInstance();
queryAllProjects();
recyclerView.setAdapter(new ProjectRecyclerViewAdapter(projects, ...
...
private void queryAllProjects() {
projects = new ArrayList<>();
//I've already tried to make a local list and return that, however,
//the compiler would force me to declare the list as final here, and it wouldn't solve anything.
db.collection("projects")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
Project project = document.toObject(Project.class);
projects.add(project);
}
Log.d(TAG, "After for loop: " + projects.toString());
//Here the list is OK. Filled with projects.
//I'd like to save the state of the list from here
} else {
Log.d(TAG, "Error getting document: ", task.getException());
Toast.makeText(getContext(), R.string.error, Toast.LENGTH_SHORT).show();
}
}
});
Log.d(TAG, "End of method: " + projects.toString());
//Oddly enough, this log displays before the other logs.
//Also, the list is empty here, which is probably what I'm unintentionally feeding into the Recycler View's adapter
}
Here's the official documentation I've been following
https://firebase.google.com/docs/firestore/query-data/get-data#custom_objects
Upvotes: 2
Views: 1318
Reputation: 138824
You cannot use now something that hasn't been loaded yet. With other words, you cannot simply make your projects
ArrayList as a global variable and use its value outside the onComplete()
method because it will always be null
due the asynchronous behaviour of this method. This means that by the time you are trying to use the following log statement:
Log.d(TAG, "End of method: " + projects.toString());
The data hasn't finished loading yet from the database and that's why is not accessible.
A quick solve for this problem would be to move this line of code inside the onComplete()
method, otherwise I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.
There is also antoher answer that shows how to get your list outside the callback.
Upvotes: 1
Reputation: 323
projects.add(project);
adapter.notifyDataSetChange()
call notifyDataSetChange() after list add
Upvotes: 0