Search code examples
androidfirebasefirebase-remote-config

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)


Solution

  • 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)