Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FirebaseRemoteConfigClientException on production (Android)

What have I done so far...

I am using Tasks.await blocking mechanism for firebase calls in worker threads for avoiding callbacks.

I am using a worker thread (JobIntentService) for some initialization progress. JobIntentService starts when app opens and runs only once. below is my worker thread code

    if (isDeviceConnectedToInternet()) {
        Tasks.await(FirebaseConfigHelper.getRemoteConfig().fetchAndActivate()); //error here
        initFirebaseConfigVariables();
        // other codes
    }

//FirebaseConfigHelper.java
public static FirebaseRemoteConfig getRemoteConfig() {
    FirebaseRemoteConfig mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
    mFirebaseRemoteConfig.setDefaultsAsync(R.xml.remote_config_defaults);
    return mFirebaseRemoteConfig;
}

I am using

implementation 'com.google.firebase:firebase-config:19.0.4'

About the error

It is working fine in testing devices. I tested in another 15 Devices in Firebase Test Lab. There was no issues at all. but when I released to production this error occurred in some specific Mi and Samsung devices.

Error log

I was able to get only this log, because error happens in production

java.util.concurrent.ExecutionException:
com.google.firebase.remoteconfig.FirebaseRemoteConfigClientException:
The client had an error while calling the backend!  at
com.google.android.gms.tasks.Tasks.zzb(Unknown Source:61)   at
com.google.android.gms.tasks.Tasks.await(Unknown Source:23) at
com.maju.myapp.service.SyncWithFirebaseJobIntentService.syncWithFirebaseConfig(SyncWithFirebaseJobIntentService.java:207)   at
com.maju.myapp.service.SyncWithFirebaseJobIntentService.onHandleWork(SyncWithFirebaseJobIntentService.java:55)  at
androidx.core.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:392)   at
androidx.core.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:383)   at
android.os.AsyncTask$3.call(AsyncTask.java:378) at
java.util.concurrent.FutureTask.run(FutureTask.java:266)    at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at
java.lang.Thread.run(Thread.java:919)Caused by:
com.google.firebase.remoteconfig.FirebaseRemoteConfigClientException:
The client had an error while calling the backend!  at
com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient.fetch(com.google.firebase:firebase-config@@19.0.4:194)  at
com.google.firebase.remoteconfig.internal.ConfigFetchHandler.fetchFromBackend(com.google.firebase:firebase-config@@19.0.4:278)  at
com.google.firebase.remoteconfig.internal.ConfigFetchHandler.fetchFromBackendAndCacheResponse(com.google.firebase:firebase-config@@19.0.4:251)  at
com.google.firebase.remoteconfig.internal.ConfigFetchHandler.fetchIfCacheExpiredAndNotThrottled(com.google.firebase:firebase-config@@19.0.4:191)    at
com.google.firebase.remoteconfig.internal.ConfigFetchHandler.lambda$fetch$0(com.google.firebase:firebase-config@@19.0.4:160)    at
com.google.firebase.remoteconfig.internal.ConfigFetchHandler$$Lambda$1.then(Unknown
Source:4)   at com.google.android.gms.tasks.zzf.run(Unknown
Source:2)   ... 3 moreCaused by: java.net.ConnectException: Failed to
connect to
firebaseremoteconfig.googleapis.com/2404:6800:4007:809::200a:443    at
com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:147)    at
com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)  at
com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186) at
com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)  at
com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)   at
com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)    at
com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)    at
com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)   at
com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)   at
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:262)   at
com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:219) at
com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:30)  at
com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient.setFetchRequestBody(com.google.firebase:firebase-config@@19.0.4:321)    at
com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient.fetch(com.google.firebase:firebase-config@@19.0.4:182)  ...
9 more
  1. Why this is happening?
  2. How to avoid it?

(Callbacks are making code ugly and messy, for making clean code I prefer Tasks.await)

like image 828
majurageerthan Avatar asked Sep 13 '25 16:09

majurageerthan


2 Answers

An API that makes an app crash, with no option to catch the exception, when a device is offline or the connection drops while accessing it. Amazing. But interestingly, using addOnCompleteListener instead of await works fine.

Hence there's a solution, add and use this helper instead:

suspend fun fetchAndActivateRemoteConfig() = suspendCancellableCoroutine {
    Firebase.remoteConfig.fetchAndActivate().addOnCompleteListener { _ ->
        it.resume(Unit)
    }
}

It's important that you do not try to access the result of addOnCompleteListener, because doing so may trigger yet another crash that Google really does not want to fix: https://github.com/firebase/firebase-android-sdk/issues/5540

Fatal Exception: com.google.android.gms.tasks.RuntimeExecutionException: com.google.firebase.remoteconfig.FirebaseRemoteConfigClientException: Firebase Installations failed to get installation auth token for fetch.
at com.google.android.gms.tasks.zzw.getResult(com.google.android.gms:play-services-tasks@@18.0.2:3)

If you do require the true/false result, you'll need to resort to manually checking Firebase.remoteConfig.info.lastFetchStatus after this call, which doesn't seem to crash.

like image 155
0101100101 Avatar answered Sep 16 '25 05:09

0101100101


I contacted Firebase Support for this issue

They said

This happens if the connection of the device user had an issue as our SDK tried to call the fetch of data, and it would cause “The client had an error while calling the backend!” error. With that, it looks like you’re doing the right thing on validating the connectivity on your recent updates before you fetch the remote config data. You can check our implementation here that you could visualize our call that would trigger this issue.

You could use the Android network debugger to simulate the network calls, so you could catch your handling mechanism to ensure that your actual device has a proper connectivity on doing the fetch.

So the problem might be the network connectivity of the device. I check the network connectivity in recent updates. but still I am getting this error in some devices. The reason may be the the poor quality of the Internet connection at the moment of the devices (@Tash Pemhiwa suggested in comment)

like image 38
majurageerthan Avatar answered Sep 16 '25 07:09

majurageerthan