19

In an Android application using Firebase, I need to execute long operations in background once Firebase returns a query answer. E.g.:

query.addListenerForSingleValueEvent(new ValueEventListener() {
   @Override
   public void onDataChange(DataSnapshot data) {
         dosomething very long. . .
         then call a callback forUI thread
   }

I know that firebase execute the query in asynchronous mode but the onDataChange() method seems to be always executed in the main UI Thread, even if I try to call the query in a custom background Thread.

Does anyone knows how to manage this use case?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
ThierryC
  • 1,794
  • 3
  • 19
  • 34

2 Answers2

24

The callbacks for your Firebase listeners are indeed executed on the main UI thread.

If you need to do heavy operations in a callback, spin up an AsyncTask and do the work there. The AsyncTask.doInBackground() method executes on a different thread, so it won't block the Android UI. But AsyncTask. onPostExecute() executes on the main thread again, so you can update your UI views from there.

If you're using Cloud Firestore, see Abhriya Roy's answer on how to get the callbacks on a background thread.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • ok it's clearer now. I will launch an async task directly in the onDataChange() method, and this task will execute the callback UI Listener at the end. – ThierryC Mar 04 '16 at 08:58
  • 13
    Is there a way to set the thread where you want to get the callback action back? – Marco Hernaiz Aug 16 '16 at 19:04
  • 1
    Frank, do you have that idea in mind? to be able to select the thread you want to return the Firebase callback? – Marco Hernaiz Sep 22 '16 at 17:27
  • 1
    Thanks I didnt know the listeners happened in the main UI thread and it was driving me crazy – Totic Nov 16 '16 at 07:40
  • I'm not a fan of AsyncTasks and I usually prefer something like this --> https://github.com/CodingDoug/white-label-event-app/commit/917ff279febce1977635226fe9181cc1ff099656 – Sotti Jun 09 '17 at 23:11
  • 1
    @wonsuc That answer applies to Cloud Firestore, while this question is about Realtime Database. As far as I know, the option to specify the callback thread is still the same there. – Frank van Puffelen Aug 15 '20 at 14:22
  • @Frank van Puffelen My apologies, I was confused about OP's question with Firestore, only `AsyncTask` should be changed to `RxJava` or Kotlin's `Coroutine`. – wonsuc Aug 18 '20 at 06:37
6

Might be a little too late to the party, but if you want Firebase to return call backs on the background thread, you can use the BACKGROUND_EXECUTOR from com.google.firebase.firestore.util.Executors.BACKGROUND_EXECUTOR like

.addOnCompleteListener(BACKGROUND_EXECUTOR, OnCompleteListener<Void> {
   ...
}

There are other executers as well like -

DEFAULT_CALLBACK_EXECUTOR
DIRECT_EXECUTOR 
Abhriya Roy
  • 1,338
  • 17
  • 23