minifyEnabled w aplikacji na Androida przerywa wywołania GoogleApi [duplikat]

Dec 16 2020

TLDR - aplikacja na Androida ma problemy z Google API, gdy minifyEnabled ma wartość true.

Istnieje aplikacja na Androida, która wykorzystuje Google API do tworzenia wydarzeń i spotkań Google. Używam dość standardowych narzędzi do pracy z tych interfejsów API - GoogleAuthorizationCodeFlow, com.google.api.services.calendar.Calendar, com.google.api.services.calendar.model.Event. Używam metody autoryzacji "Aplikacje serwera WWW" zamiast "Zainstalowane aplikacje" bez powodu, ale fakt, że już pierwsza z nich zadziałała. Wszystko działa dobrze w moim trybie debugowania, ale kiedy przechodzę do trybu wydania, pojawiają się problemy.

  • GoogleClientSecretsstaje się niezdolny do przetwarzania danych Secrets.json console.developers.google.com. Ten sam plik działa dobrze w trybie debugowania, ale teraz GoogleClientSecrets.getDetailszwraca wartość null. Zabawny fakt - GoogleClientSecrets.toString/GoogleClientSecrets.toPrettyStringpokaż dane z pliku, ale wydaje się, że brakuje w nim wszystkich plików konfiguracyjnych cudzysłowów. W końcu to naprawiono (teraz tworzę sekrety bezpośrednio za pomocą clientId / clientSecret, bez pliku json), ale dlaczego problem pojawia się na pierwszym miejscu?
  • po tej poprawce flow.newAuthorizationUrl().setRedirectUri(redirectUrl).build()daje mi https://accounts.google.com/o/oauth2/authzamiast https://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. Większość „względnych” części jest pomijana, chociaż redirectUrl i clientId są poprawnie odczytywane i zapisywane - ale nie ma po nich śladu w adresie URL. Zostało to naprawione przez dodanie -keep class com.google.api.client.googleapis.auth.oauth2.*do mojego proguard-rules.pro. Co już wygląda na bardziej obejście niż prawdziwe rozwiązanie, ale później sytuacja się pogorszy.
  • po tej poprawce, kiedy to zrobię
    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();

z doskonale dobrym zdarzeniem, które działa dobrze bez minifikacji, wtedy otrzymuję

c.f.b.a.b.c.b: 404 Not Found
{
   "errors" : [ {
     "domain" : "global",
     "reason" : "notFound",
     "message" : "Not Found"
   } ],
   "code" : 404,
   "message" : "Not Found"
}

Można to naprawić -keep class com.google.api.services.calendar.* { *; }w pliku myproguard-rules.pro

  • po tej poprawce, ta sama próba wstawienia zdarzenia daje mi
    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)

Po kilku testach zauważyłem, że wszystko powyższe pojawia się tylko wtedy, gdy minifyEnabled jest prawdą. Z minifyEnabled false wszystko działa jak urok. Do tej pory znalazłem 3 rozwiązania

  • minifyEnabled false. Lubię jednak moje pliki zminimalizowane w wydaniu
  • dontobfuscatei dontshrinkw proguard-rules.pro. Pomaga, ale ogranicza efekt zmiękczenia.
  • keep class * { *; }w proguard-rules.pro. Pomaga, ale ogranicza efekt zmiękczenia.

Nie mogę uwierzyć, że standardowa opcja, taka jak minifyEnabled, zepsułaby coś w rodzaju GoogleAuthorizationstandardowych narzędzi com.google.api.client.*na tak wielką skalę. Mogę jednak wierzyć, że popełniam głupie i oczywiste błędy. Moja ostatnia słomka na razie to „Zainstalowane” z dala od „Aplikacji serwera WWW”, ale nie pokładam w tym zbyt wielkich nadziei - gdyby to było główne źródło problemów, dlaczego miałoby działać bez minifikacji ...

Dlaczego może się zdarzyć opisane zachowanie? Co ja robię źle?

Odpowiedzi

IvanGarza Dec 16 2020 at 00:22

Dodanie wyjątków reguł do proguard-rules.propliku nie jest rzadką praktyką, jeśli napotkasz problemy z zaciemnianiem w kompilacji wydania.

Sama praca z ProGuard to cały temat, ale nie myśl, że dodanie wyjątków do narzędzia zaciemniania aplikacji podważa bezpieczeństwo aplikacji lub coś takiego. Niektóre interfejsy API i wzorce kodowania wymagają po prostu kilku wyjątków, aby działały poprawnie; np. klasy / modele danych i wszystko, co pochodzi z warstwy JNI, zawsze wymaga de-zaciemniania.

Oto krótki artykuł na ten temat, jeśli nadal nie jesteś przekonany.