Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to continue Firebase Task on the same thread

I have some code executed on an SyncAdapter on the background thread that looks like this

Task<DocumentSnapshot> docTask = FirebaseFirestore.
          getInstance().
          collection("users_dummy").
          document("ID1").
          get();

How can I continue on the background thread when this task has been finished?

I tried to the .addOnCompleteListener after the get

 .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>()
                {
                    @Override
                    public void onComplete(@NonNull Task<DocumentSnapshot> task)
                    {
                       // DOESN'T WORK, THIS IS THE MAIN THREAD

                    }
                });

but as noted here, the callback is done on the UI or main thread, which actually throws a

java.lang.IllegalStateException: Must not be called on the main application thread

when I perform code like Tasks.await(some task)

Full example here (ignore at will):

    private void performTheCodeThatDoesNotWork()
    {

        Task<DocumentSnapshot> docTask = FirebaseFirestore.getInstance().collection("users_dummy")
                .document("ID1").get()
                .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>()
                {
                    @Override
                    public void onComplete(@NonNull Task<DocumentSnapshot> task)
                    {

                        try
                        {
                            // Query the second one but block this time
                            Task<DocumentSnapshot> secondId = FirebaseFirestore.getInstance().collection("users_dummy")
                                    .document("ID2").get();

/* THIS WILL THROW THE EXCEPTION ->*/ Tasks.await(secondId);
                            DocumentSnapshot result = secondId.getResult();
                        }
                        catch (Exception ex)
                        {
                            ex.printStackTrace();
                        }

                        Log.i("TAG", "Result is there but never reached");
                    }
                });

        Log.i("TAG", "Im here quickly, because async");

    }

I've tried Task.continueWith but with the same results. Do I need to facilitate an Executor and call addOnCompleteListener with it like in this doc stating leaking activities?

Or am I missing something trivial about this issue? Is it that hard to continue on some thread but perform blocking calls there?

like image 366
Samuel Avatar asked Mar 22 '26 13:03

Samuel


1 Answers

If you want your callback to be invoked on a thread other than the main thread, you will have to provide an Executor with the listener that will schedule the invocation of the listener on a non-main thread. This is your only option.

Tasks.await() is almost never the right thing to use, especially not on the main thread, since it may block. It's only for use on background threads, and only when you absolutely know you need blocking behavior.

like image 89
Doug Stevenson Avatar answered Mar 24 '26 03:03

Doug Stevenson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!