-
Notifications
You must be signed in to change notification settings - Fork 631
Description
[READ] Step 1: Are you in the right place?
yes
[REQUIRED] Step 2: Describe your environment
- Android Studio version: 3.6.1
- Firebase Component: firebase-messaging
- Component version: 20.1.7
[REQUIRED] Step 3: Describe the problem
Sometimes, after calling task.getResult().getToken()
my app crashes with the following stack.
This happens occasionally, usually once a week. After that the app keeps crashing on startup and the only thing that stops it from crashing is to delete the cache from Android's app settings.
I suspect it has to do with caching of the token because after cleaning the cache will make the problem goes away (until the next cache refresh)
java.lang.IllegalArgumentException: method POST must have a request body.
com.android.okhttp.Request$Builder.method(Request.java:267)
com.android.okhttp.internal.huc.JavaApiConverter.createOkResponseForCacheGet(JavaApiConverter.java:216)
com.android.okhttp.internal.huc.CacheAdapter.get(CacheAdapter.java:53)
com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:316)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:483)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:135)
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:266)
com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:219)
com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:30)
com.google.firebase.installations.remote.FirebaseInstallationServiceClient.writeRequestBodyToOutputStream(com.google.firebase:firebase-installations@@16.3.0:208)
com.google.firebase.installations.remote.FirebaseInstallationServiceClient.writeGenerateAuthTokenRequestBodyToOutputStream(com.google.firebase:firebase-installations@@16.3.0:248)
com.google.firebase.installations.remote.FirebaseInstallationServiceClient.generateAuthToken(com.google.firebase:firebase-installations@@16.3.0:369)
com.google.firebase.installations.FirebaseInstallations.fetchAuthTokenFromServer(com.google.firebase:firebase-installations@@16.3.0:471)
com.google.firebase.installations.FirebaseInstallations.doNetworkCall(com.google.firebase:firebase-installations@@16.3.0:342)
com.google.firebase.installations.FirebaseInstallations.lambda$doRegistrationInternal$0(com.google.firebase:firebase-installations@@16.3.0:330)
com.google.firebase.installations.FirebaseInstallations$$Lambda$5.run(Unknown Source:4)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
java.lang.Thread.run(Thread.java:919)
Note that I'm using okhttp 3.12.10 - the latest version that supports Android 4.4 (API 19). In okhttp 4.0, the code that throws this error is gone.
Looking in the okhttp source code, it seems that the problem is just as the error message says: FirebaseInstallationServiceClient is posting with body == null
. I'd look in FirebaseInstallationServiceClient.writeGenerateAuthTokenRequestBodyToOutputStream
but the source code is not in this git repository.
In my various emails with Firebase support they hinted that some of the initialization options are missing (API key, Project ID, etc.) but I'm using the automatic initialization with the gradle plugin and google-services.json exactly as described in the docs. Furthermore, I validated that the info from google-services.json is merged into the apk's resources and that firebase is initialized properly (by calling FirebaseApp.initializeApp() which lead to a log stating: "FirebaseApp name [DEFAULT] already exists!"
Steps to reproduce:
First you need to compile with okhttp 3.12.10 (any 3.12.x will do)
dependencies {
implementation("com.squareup.okhttp3:okhttp:3.12.10")
}
Then call task.getResult().getToken()
as in the code below.
Run it for some time, probably several times every day for a week, and it will probably happen. I think this has to do with caching of the token because after this crashes, it will keep on crashing until you clear the cache.
Relevant Code:
FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
@Override
public void onComplete(@NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
return;
}
String token = task.getResult().getToken();
}
});