TLDR - Android app has problems with Google API when minifyEnabled is true.
There is an Android app that uses Google API for creating events and google meetings. I use pretty standard tools for working with those APIs - GoogleAuthorizationCodeFlow
, com.google.api.services.calendar.Calendar
, com.google.api.services.calendar.model.Event
. I am using "Web server applications" auth way instead of "Installed applications" for no good reason but the fact I already made the first one work. All works fine in my debug mode, but when I go to release mode, problems arise.
GoogleClientSecrets
becomes unable to process secrets.jsonconsole.developers.google.com
gave me. Same file works fine in debug mode, but nowGoogleClientSecrets.getDetails
returns null. Funny fact -GoogleClientSecrets.toString/GoogleClientSecrets.toPrettyString
show data from file, but it seems to be missing all quotes config file has. It eventually fixed (now I am creating secrets directly using clientId/clientSecret, without json file), but why problem appears first place?- after that fix,
flow.newAuthorizationUrl().setRedirectUri(redirectUrl).build()
gives mehttps://accounts.google.com/o/oauth2/auth
instead ofhttps://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&client_id=<myClientId>&redirect_uri=<myRedirect>&response_type=code&scope=https://www.googleapis.com/auth/calendar
. Most of "relative" part is skipped, although redirectUrl and clientId are read and saved correctly - but there is no trace of them in Url. This was fixed with adding-keep class com.google.api.client.googleapis.auth.oauth2.*
to myproguard-rules.pro
. Which is already looks like more of workaround, than real solution, but things get worse later. - after that fix, when I do
Credential credential = getCredential(context);
Calendar service = new Calendar.Builder(HTTP_TRANSPORT,
JSON_FACTORY,
credential)
.setApplicationName(APPLICATION_NAME)
.build();
service.events().insert(calendarId, event)
.setConferenceDataVersion(1)
.setSupportsAttachments(true)
.execute();
with a perfectly good event that works fine without minification, then I get
c.f.b.a.b.c.b: 404 Not Found
{
"errors" : [ {
"domain" : "global",
"reason" : "notFound",
"message" : "Not Found"
} ],
"code" : 404,
"message" : "Not Found"
}
This can be fixed with -keep class com.google.api.services.calendar.* { *; }
in my proguard-rules.pro
- after that fix, same attempt to insert event gives me
W/System.err: java.lang.IllegalArgumentException: key creator
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:889)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:382)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:355)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
After some tests, I noticed, that all of the above appears only when minifyEnabled is true. With minifyEnabled false, all works like a charm. So far I found 3 solutions
minifyEnabled false
. I kind of like my files minified in release thoughdontobfuscate
anddontshrink
inproguard-rules.pro
. Helps, but reduces the effect of minifying.keep class * { *; }
inproguard-rules.pro
. Helps, but reduces the effect of minifying.
I can't believe that a standard option like minifyEnabled would break something like GoogleAuthorization
through standard tools of com.google.api.client.*
on such a great scale. I can believe in me making some stupid and obvious mistakes, though. My last straw, for now, is going to "Installed" way from "Web server applications", but I don't exactly put big hopes here - if it was the main source of problems, why would it work without minification...
Why can the described behavior happen? What am I doing wrong?