I am trying to fetch data from a firestore collection and show it as a list in a widget, i am not too experienced on how widget logic works so i thought that there might be a function that invokes the widget view to be updated when the data is filled.
I basically fetch the information from a RemoteViewFactory
class, but since the firebase functions are all asynchronous, i don't know how to make the widget to wait until the data is filled, or invoke a function within the class that would invoke the update.
Currently my class looks like this:
public class TaskDataProvider implements RemoteViewsService.RemoteViewsFactory {
private static final String TAG = TaskDataProvider.class.getSimpleName();
private static final int TOTAL = 10;
List<Task> tasks = new ArrayList<>();
private Context context;
public TaskDataProvider(Context context) {
this.context = context;
}
@Override
public void onCreate() {
this.loadData(value -> this.tasks = value);
}
@Override
public void onDataSetChanged() {
this.loadData(value -> this.tasks = value);
}
@Override
public void onDestroy() {
}
@Override
public int getCount() {
return this.tasks.size();
}
@Override
public RemoteViews getViewAt(int position) {
final RemoteViews remoteViews = new RemoteViews(this.context.getPackageName(), R.layout.widget_task_item);
final Task currentTask = this.tasks.get(position);
remoteViews.setTextViewText(R.id.widget_task_item_title, currentTask.getTitle());
remoteViews.setTextViewText(R.id.widget_task_item_description, currentTask.getDescription());
return remoteViews;
}
@Override
public RemoteViews getLoadingView() {
return null;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return true;
}
private void loadData(ResultListener<List<Task>> resultListener) {
FirebaseAuth auth = FirebaseAuth.getInstance();
FirebaseUser user = auth.getCurrentUser();
if (user != null) {
this.retrieveTasks(user.getUid(), resultListener);
}
}
private void retrieveTasks(String userId, ResultListener<List<Task>> resultListener) {
FirebaseFirestore firestore = FirebaseFirestore.getInstance();
firestore.collectionGroup(this.context.getString(R.string.database_project_task_collection_name))
.whereEqualTo(Task.FIELD_ASSIGNEE, userId)
.whereEqualTo(Task.FIELD_STATUS, TaskStatus.STATUS_OPEN)
.get()
.addOnCompleteListener(task -> {
if (!task.isSuccessful()) {
Log.e(TAG, "Unable to retrieve task list", task.getException());
} else {
final QuerySnapshot result = task.getResult();
if (result != null) {
Log.d(TAG, String.format("Found tasks: %d", result.size()));
resultListener.onResult(result.toObjects(Task.class));
}
}
});
}
}
Both onCreate
and onDataSetChanged
are calling loadData
which takes care of fetching the collection data from firestore, i know that at the time both onCreate
and onDataSetChanged
finished running the tasks
property is still not filled and therefore nothing is filled in the list i am rendering in the widget.
How can i properly fetch information from firebase and then fill a ListView
widget with that information?