How to return query results to the Firestore within the Ackground method?

Asked

Viewed 76 times

-1

I’m working on a Cookbook app to learn how to use Firebase resources and I’m working on an Activity that should list all recipes already registered by the user.

The routines to record data in the database are working perfectly, but I came across some problems at the time of reading this data, in short I receive the data from the database but I can’t pass them to my graphical interface.

I saw that this problem caused the delay that Firestore has to return the data and that this could be solved by implementing parallelism in the code, and after reading a little on the subject I tried to make the implementation of Async Task and its methods but I could not solve the problem.

In short, the Ackground method returns its result and calls the onPostExecute() method (which in turn calls the methods that power the graphical interface) before actually receiving the results from the Firestore.

In the image below, a print of the logs of the app, you can see that the methods are working and being called in the correct order, but doInBackground is returning its results before completing the call to the bank. In yellow are the logs of async task life cycle methods, in red the results returned by Firestore.

Log que mostra a ordem dos retornos e de chamadas dos métodos do ciclo de vida da minha async task, além de mostrar o retorno

Implementation of the Ackground class()

    @Override
protected ArrayList<Receita> doInBackground(Void... voids) {
    //leitura do banco
    db.collection("receitas")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            Log.d("Firestore:readRecepie", document.getId() + " => " + document.getData());

                            Receita receita = document.toObject(Receita.class);
                            Log.d("Salvando a receita:", receita.getNome());

                            receitas.add(receita);
                            publishProgress();
                        }
                    } else {
                        Log.w("Firestore", "Error getting documents.", task.getException());
                    }
                }
            });

    //O problema está aqui, ele tá retornando essa lista antes de terminar a leitura do metodo interno
    Log.d("Async:doInBackground", "vai retornar o doInBackground");
    return receitas;

1 answer

0

The return of the list of recipes has to happen within the

if (task.isSuccessful()) {

    for (...) {

        ...

        receitas.add(receita);

    } 

    return receitas

} 

Thus, after obtaining the query data successfully from the Firestore and going through the entire Firestore list and adding the items in the recipes list is that the result will be returned.

And what about the return of the method? Since you are changing the position of the line? For this, I suggest you create a response object successfully and error. Successfully return a date with the list And in case of error return on if’s Else (task.isSuccessful()) {

Read about Mutablelivedata, maybe facilitate with treatments for external queries or that have some delay, and so for example update your Activity only when the Firestore task is successfully completed or error

Browser other questions tagged

You are not signed in. Login or sign up in order to post.