3

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?

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Oscar Reyes
  • 4,223
  • 8
  • 41
  • 75

0 Answers0