google-services.json dla różnych smaków produktu

453

Aktualizacja: GCM jest przestarzałe, użyj FCM

Wdrażam nowy Google Cloud Messaging, postępując zgodnie ze wskazówkami ze strony Google Developers tutaj

Udało mi się to uruchomić i przetestować. Ale moim problemem jest teraz to, że mam różne smaki produktów z różnymi identyfikatorami aplikacji / nazwa_pakietu i innym identyfikatorem projektu Google Cloud Messaging. Trzeba google-services.jsonje umieścić w /app/google-services.jsonfolderze nie smaki.

Czy jest jakiś sposób, aby zmienić google-services.jsonkonfigurację dla wielu smaków?

gentra
źródło
W przypadku Maven zaimplementowaliśmy coś podobnego, używając profili maven i osobnych plików właściwości dla każdego profilu
sakis kaliakoudas
1
jeśli chcesz tylko użyć identyfikatora nadawcy, wygeneruj klucz bez nazwy pakietu z konsoli Google.
Murtaza Khursheed Hussain
Linia apply plugin: 'com.google.gms.google-services'w pliku gradle wydaje się wstawiać gcmciągi do app/build/generated/res/google-services/debug/values/values.xml...
Alexander Farber,
Najlepszą odpowiedzią Znalazłem za to na to pytanie
Estel
Przeczytaj to: firebase.googleblog.com/2016/08/… Obejmuje wszystkie możliwości i kompromisy.
Albert Vila Calvo,

Odpowiedzi:

509

Google zawarło obsługę smaków w wersji 2.0 wtyczki usług Play. Od tej wersjigradle plugin com.google.gms:google-services:2.0.0-alpha3

możesz to zrobić

app/src/
    flavor1/google-services.json
    flavor2/google-services.json

Wersja 3.0.0 wtyczki wyszukuje plik json w tych lokalizacjach (biorąc pod uwagę, że masz flavorwersję flav1 i typ kompilacji debug):

/app/src/debug/google-services.json
/app/src/debug/flavor1/google-services.json
/app/google-services.json

To działało dla mnie nawet przy użyciu flavourDimensions. Mam darmowy i płatny w jednym wymiarze, a Mock & Prod w drugim wymiarze. Mam również 3 typy buildów: debugowanie, wydanie i inscenizacja. Tak to wygląda w moim projekcie dla smaku FreeProd:

wprowadź opis zdjęcia tutaj

Ile plików google-services.json będzie zależeć od cech twojego projektu, ale będziesz potrzebował co najmniej jednego pliku json dla każdego projektu Google.

Jeśli chcesz uzyskać więcej informacji o tym, co ta wtyczka robi z tymi plikami json, oto: https://github.com/googlesamples/google-services/issues/54#issuecomment-165824720

Link do oficjalnych dokumentów: https://developers.google.com/android/guides/google-services-plugin

Wpis na blogu ze zaktualizowanymi informacjami: https://firebase.googleblog.com/2016/08/organizing-your-firebase-enabled-android-app-builds.html

I przejdź tutaj, aby sprawdzić najnowszą wersję tej wtyczki: https://bintray.com/android/android-tools/com.google.gms.google-services/view

Yair Kukielka
źródło
13
Z jakiegoś powodu to dla mnie nie działa - pojawia się błąd kompilacji stopniowej - File google-services.json is missing from module root folder. The Google Services Plugin cannot function without it.dlatego za każdym razem będę musiał kopiować plik smakowy do folderu głównego za pomocą skryptu kompilacji.
dodgy_coder
2
Działa jak urok, dzięki Bogu za to. google-services.json i ten zupełnie nowy sposób korzystania z apis wydaje się krokiem wstecz. Nie wiem, jak to powinno być łatwiejsze.
RED_
140
googl-services.json to obrzydliwość ... w jaki sposób zarządzanie jakimś szalonym plikiem json jest łatwiejsze niż tylko podłączenie klucza API i identyfikatora nadawcy? Proszę google, przestań bzdury
Greg Ennis
19
Najnowsza wersja generatora plików konfiguracyjnych umieszcza wiele właściwości w tym samym pliku konfiguracyjnym, potrzebując tylko jednej z nich na poziomie aplikacji, zamiast osobnych na poziomie smaku. Musisz tylko upewnić się, że obie konfiguracje są generowane w tym samym polu „Nazwa aplikacji”.
sroskelley
5
Począwszy od Androida Studio 3.1.4, używanie /app/src/flavor1/google-services.json nie działa. Pliki muszą znajdować się w /app/src/flavor1/debug/google-services.json i /app/src/flavor1/release/google-services.json.
pielęgniarka
71

AKTUALIZACJA: Poniższe objaśnienie dotyczy jednego projektu Android Studio z jednym projektem Firebase i różnymi aplikacjami Firebase w tym projekcie. Jeśli celem jest posiadanie różnych plików JSON dla różnych aplikacji Firebase w różnych projektach Firebase w ramach tego samego projektu Android Studio (lub jeśli nie wiesz, jaka jest różnica), spójrz tutaj. .

Potrzebujesz jednej aplikacji Firebase na identyfikator aplikacji na Androida (zwykle nazwa pakietu). Często występuje jeden identyfikator aplikacji dla każdego wariantu kompilacji Gradle (jest to prawdopodobne, jeśli użyjesz typów kompilacji Gradle i smaków kompilacji Gradle)


Począwszy od usług Google 3.0 i korzystania z Firebase , nie trzeba tworzyć różnych plików dla różnych smaków. Tworzenie różnych plików dla różnych smaków może być niejasne lub proste, jeśli masz komponenty ProductFlavours i Build, które się ze sobą komponują.

W tym samym pliku będziesz mieć wszystkie konfiguracje, których potrzebujesz dla wszystkich typów kompilacji i smaków.

W konsoli Firebase musisz dodać jedną aplikację na nazwę pakietu. Wyobraź sobie, że masz 2 smaki (dev i live) i 2 typy kompilacji (debugowanie i wydanie). W zależności od konfiguracji, ale prawdopodobnie masz 4 różne nazwy pakietów, takie jak:

  • com.stackoverflow.example (na żywo - wydanie)
  • com.stackoverflow.example.dev (live - dev)
  • com.stackoverflow.example.debug (debugowanie - wydanie)
  • com.stackoverflow.example.dev.debug (debugowanie - dev)

Potrzebujesz 4 różnych aplikacji na Androida w konsoli Firebase. (Na każdym z nich musisz dodać SHA-1 do debugowania i na żywo dla każdego komputera, którego używasz)

Gdy pobierasz plik google-services.json, tak naprawdę nie ma znaczenia, z której aplikacji go pobierzesz, wszystkie zawierają te same informacje związane ze wszystkimi Twoimi aplikacjami.

Teraz musisz zlokalizować ten plik na poziomie aplikacji (app /).

wprowadź opis zdjęcia tutaj

Jeśli otworzysz ten plik, zobaczysz, że jeśli zawiera wszystkie informacje o wszystkich nazwach pakietów.

Punktem bólu jest wtyczka. Aby go uruchomić, musisz zlokalizować wtyczkę na dole pliku. Więc ta linia ...

apply plugin: 'com.google.gms.google-services'

... musi znajdować się na dole pliku build.gradle aplikacji.

W przypadku większości wspomnianych tutaj dotyczy to również poprzednich wersji. Nigdy nie miałem różnych plików dla różnych konfiguracji, ale teraz konsola Firebase jest łatwiejsza, ponieważ zapewniają one jeden plik ze wszystkim, czego potrzebujesz do wszystkich konfiguracji.

Sotti
źródło
Generuję mój z developers.google.com/mobile/add i istnieje tylko jedna możliwość umieszczenia jednej nazwy pakietu. Gdzie jest miejsce Firebase do skonfigurowania tego lub jak wygląda plik google-services.json z wieloma
odmianami
@CQM Zaktualizowałem odpowiedź dodając kilka linków. Możesz sprawdzić dokumentację Firebase i wygenerować plik JSON w konsoli Firebase zgodnie z opisem w odpowiedzi.
Sotti
7
To naprawdę dobra odpowiedź i powinna być jedyną właściwą odpowiedzią na to pytanie.
Nando
1
Odkryłem to sam, kiedy napotkałem ten sam problem, tak jak to opisałeś powyżej. Przybyłem tutaj, aby przesłać odpowiedź dla potomnych, tylko po to, by stwierdzić, że już to zrobiłeś. W wersji 3.0.0 jest to z pewnością najlepsza odpowiedź.
Tash Pemhiwa
6
Pamiętaj, że działa to tylko wtedy, gdy wszystkie smaki są w ramach tego samego projektu bazy ogniowej. Jeśli korzystasz z wielu projektów (zazwyczaj utrzymuję programistę i scenę w jednym projekcie firebase i sprzedaję w osobnym dedykowanym projekcie prod na innym koncie Google), potrzebujesz rozwiązania przedstawionego przez Yaira Kukielkę. Wygląda na to, że wtyczka obsługuje różne ścieżki - podczas kompilacji pojawi się wskazówka, gdzie poszła wtyczka w poszukiwaniu pliku google-services.json: „Nie można znaleźć google-services.json podczas wyszukiwania w [src / prod / debug, src / debug / prod, src / prod, src / debug, src / prodDebug] "
JHH
43

Napisałem średni post na ten temat.

Miałem podobny problem (używanie BuildTypes zamiast Flavours) i tak go naprawiłem.

Skorzystaj z systemu zarządzania zależnościami firmy Gradle. Stworzyłem dwa zadania switchToDebugi switchToRelease. Wymagaj, aby w dowolnym momencie assembleReleasebyło uruchamiane, to switchToReleasejest również uruchamiane. To samo dotyczy debugowania.

def appModuleRootFolder = '.'
def srcDir = 'src'
def googleServicesJson = 'google-services.json'

task switchToDebug(type: Copy) {
    def buildType = 'debug'
    description = 'Switches to DEBUG google-services.json'
    from "${srcDir}/${buildType}"
    include "$googleServicesJson"
    into "$appModuleRootFolder"
}

task switchToRelease(type: Copy) {
    def buildType = 'release'
    description = 'Switches to RELEASE google-services.json'
    from "${srcDir}/${buildType}/"
    include "$googleServicesJson"
    into "$appModuleRootFolder"
}

afterEvaluate {
    processDebugGoogleServices.dependsOn switchToDebug
    processReleaseGoogleServices.dependsOn switchToRelease
}

EDYCJA: użyj processDebugFlavorGoogleServices/ processReleaseFlavorGoogleServicestask, aby zmodyfikować go na poziomie dla każdego smaku.

ZakTaccardi
źródło
Ale działa to dla buildTypes, a nie dla smaków opublikowanych przez OP
bryant1410,
1
@ bryant1410, jeśli używasz smaku - domyślam się, że zamiast tego możesz podłączyć się do zadania processDebugFlavorGoogleServices.
ZakTaccardi
Myślę, że powinieneś zmienić to w swojej odpowiedzi, ponieważ pytanie dotyczyło smaków, a nie typów buildów. Myślę, że możesz pozostawić tę odpowiedź jako drugą opcję
bryant1410
1
@ bryant1410 logika jest zasadniczo taka sama dla smaku lub buildType. powinieneś być w stanie to
rozgryźć
1
@IgorGanapolsky tak, dwie wersje
ZakTaccardi
13

Cóż, mam ten sam problem i nie mogłem znaleźć żadnego idealnego rozwiązania. To tylko obejście. Zastanawiam się, jak Google nie pomyślał o smakach ...? I mam nadzieję, że wkrótce zaproponują lepsze rozwiązanie.

Co ja robię:

Mam dwa smaki, w każdym z nich umieszczam odpowiedni plik google-services.json: src/flavor1/google-services.jsoni src/flavor2/google-services.json.

Następnie w gradacji kompilacji kopiuję plik w zależności od smaku do app/katalogu:

android {

// set build flavor here to get the right gcm configuration.
//def myFlavor = "flavor1"
def myFlavor = "flavor2"

if (myFlavor.equals("flavor1")) {
    println "--> flavor1 copy!"
    copy {
        from 'src/flavor1/'
        include '*.json'
        into '.'
    }
} else {
    println "--> flavor2 copy!"
    copy {
        from 'src/flavor2/'
        include '*.json'
        into '.'
    }
}

// other stuff
}

Ograniczenie: będziesz musiał zmieniać myFlavor ręcznie za każdym razem, gdy chcesz uruchomić inny smak (ponieważ jest zakodowany na stałe).

Próbowałem wielu sposobów, aby uzyskać obecny smak kompilacji, jak afterEvaluateblisko ... nie mogłem znaleźć lepszego rozwiązania do tej pory.

Aktualizacja, inne rozwiązanie: jeden plik google-services.json dla wszystkich smaków:

Możesz również mieć różne nazwy pakietów dla każdego smaku, a następnie w konsoli programisty Google nie musisz tworzyć dwóch różnych aplikacji dla każdego smaku, a tylko dwóch różnych klientów w tej samej aplikacji. Będziesz miał tylko jeden, google-services.jsonktóry zawiera obu twoich klientów. Oczywiście zależy to od tego, jak implementujesz backend swoich smaków. Jeśli nie zostaną rozdzielone, to rozwiązanie ci nie pomoże.

ahmed_khan_89
źródło
masz na myśli, że jeśli backendy są rozdzielone, to nie będzie dla ciebie działać, wierzę
ZakTaccardi
wszystko zależy od tego, w jaki sposób zdefiniujesz smaki po obu stronach; klient i serwer. W moim przypadku różne nazwy pakietów, różne adresy URL serwerów i różne bazy danych. Tak więc serwer wyśle ​​powiadomienie do użytkownika w odpowiedniej bazie danych. Użytkownik A ma token 1 dla flavour1 i token2 dla flavour2. Jeśli masz różne wpisy do bazy danych, nie będziesz mieć problemu.
ahmed_khan_89,
Próbowałem utworzyć zadania, które kopiują, a następnie wywołują je w określonym procesie debugowania lub procesie wydawania i sądzę, że to zadziałało. Życzę tego wcześniej opublikowanego
humblerookie
1
Używanie jednego google-services.jsondla obu releasei debugdziała dla mnie, jak wspomniano w twojej aktualizacji. Myślę, że jest to najprostsze rozwiązanie, jeśli próbujesz podzielić swoją debugwersję, tak jak ja. W
celach informacyjnych
12

Zgodnie z odpowiedzią ahmed_khan_89 możesz umieścić „kopiuj kod” w smaku produktu.

productFlavors {
    staging {
        applicationId = "com.demo.staging"

        println "Using Staging google-service.json"
        copy {
            from 'src/staging/'
            include '*.json'
            into '.'
        }
    }
    production {
        applicationId = "com.demo.production"

        println "Using Production google-service.json"
        copy {
            from 'src/production/'
            include '*.json'
            into '.'
        }
    }
}

Wówczas nie musisz ręcznie zmieniać ustawień.

Kros CS Huang
źródło
2
@ZakTaccardi, ale pytanie dotyczy smaków, a nie typów kompilacji
bryant1410,
1
to nie jest tak dobre rozwiązanie jak medium.com/@ZakTaccardi/…
ZakTaccardi
2
Nie działa Spowoduje to uruchomienie obu poleceń kopiowania niezależnie od wersji kompilacji, więc json produkcyjny jest zawsze w katalogu aplikacji.
Izaak
Działa dla smaków. Nie ma potrzeby ręcznego przełączania zmiennych w build.gradle.
Vito Valov
9

Korzystam z pliku google-services.json, utworzonego tutaj: https://developers.google.com/mobile/add?platform=android&cntapi=gcm&cnturl=https:%2F%2Fdevelopers.google.com%2Fcloud-messaging % 2Fandroid% 2Fclient & cntlbl = Kontynuuj% 20Dodawanie% 20GCM% 20 Wsparcie i% 3Fconfigured% 3Dtrue

W strukturze JSON znajduje się tablica JSON zwana klientami. Jeśli masz wiele smaków, po prostu dodaj tutaj różne właściwości.

{
  "project_info": {
    "project_id": "PRODJECT-ID",
    "project_number": "PROJECT-NUMBER",
    "name": "APPLICATION-NAME"
  },
  "client": [
    {
      "client_info": {
        "mobilesdk_app_id": "1:PROJECT-NUMBER:android:HASH-FOR-FLAVOR1",
        "client_id": "android:PACKAGE-NAME-1",
        "client_type": 1,
        "android_client_info": {
          "package_name": "PACKAGE-NAME-1"
        }
      },
      "oauth_client": [],
      "api_key": [],
      "services": {
        "analytics_service": {
          "status": 1
        },
        "cloud_messaging_service": {
          "status": 2,
          "apns_config": []
        },
        "appinvite_service": {
          "status": 1,
          "other_platform_oauth_client": []
        },
        "google_signin_service": {
          "status": 1
        },
        "ads_service": {
          "status": 1
        }
      }
    },
    {
      "client_info": {
        "mobilesdk_app_id": "1:PROJECT-NUMBER:android:HASH-FOR-FLAVOR2",
        "client_id": "android:PACKAGE-NAME-2",
        "client_type": 1,
        "android_client_info": {
          "package_name": "PACKAGE-NAME-2"
        }
      },
      "oauth_client": [],
      "api_key": [],
      "services": {
        "analytics_service": {
          "status": 1
        },
        "cloud_messaging_service": {
          "status": 2,
          "apns_config": []
        },
        "appinvite_service": {
          "status": 1,
          "other_platform_oauth_client": []
        },
        "google_signin_service": {
          "status": 1
        },
        "ads_service": {
          "status": 1
        }
      }
    }
  ],
  "client_info": [],
  "ARTIFACT_VERSION": "1"
}

W moim projekcie korzystam z tego samego identyfikatora projektu, a gdy dodam drugą nazwę pakietu w powyższym adresie URL, Google udostępnia mi plik zawierający wielu klientów w danych json.

Przepraszamy za kompaktowe dane JSON. Nie mogłem poprawnie sformatować ...

Mark Martinsson
źródło
8

Plik google-services.json nie jest potrzebny do otrzymywania powiadomień. Po prostu dodaj zmienną dla każdego smaku w pliku build.gradle:

buildConfigField "String", "GCM_SENDER_ID", "\"111111111111\""

Użyj tej zmiennej BuildConfig.GCM_SENDER_ID zamiast getString (R.string.gcm_defaultSenderId) podczas rejestracji:

instanceID.getToken(BuildConfig.GCM_SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
divonas
źródło
6

1.) Co naprawdę robi google-services.json?

Postępuj zgodnie z tym: https://stackoverflow.com/a/31598587/2382964

2.) W jaki sposób plik google-services.json wpływa na projekt Android Studio?

Postępuj zgodnie z tym: https://stackoverflow.com/a/33083898/2382964

krótko po drugim adresie URL, jeśli dodasz google-services.json w swoim projekcie, musi istnieć automatycznie wygenerowany google-servicesfolder dla debugwariantu na tej ścieżce

app/build/generated/res/google-services/debug/values/values.xml

3.) Co zrobić, aby to zrobić?

dodaj zależność usług Google w project_levelbuild.gradle, możesz także użyć, version 3.0.0jeśli korzystasz z biblioteki app_compact.

// Top-level build.gradle file
classpath 'com.google.gms:google-services:2.1.2'

teraz w app_levelbuild.gradle musisz dodać na dole.

// app-level build.gradle file
apply plugin: 'com.google.gms.google-services'

4.) Gdzie umieścić plik google-service.json w swojej strukturze.

przypadek 1.) jeśli nie masz wersji build_flavor, po prostu włóż ją do /app/google-service.jsonfolderu.

przypadek 2.) jeśli masz wiele wersji build_flavor i masz w nim różne pliki google_services.json app/src/build_flavor/google-service.json.

przypadek 3.) jeśli masz wiele wersji build_flavor i masz w sobie pojedynczy plik google_services.json app/google-service.json.

Tushar Pandey
źródło
4

Nie ma potrzeby wykonywania dodatkowych skryptów.

Google zaczął dodawać inną nazwę pakietu w nazwie „android_client_info”. Wygląda jak poniżej w google-services.json

"android_client_info": {
      "package_name": "com.android.app.companion.dev"
    }

więc następujące kroki wystarczą, aby wybrać inny wybór google-services.json.

  1. Mają 2 smaki
  2. Dodaj nowy pakiet dev flavour do strony konfiguracji google analystics i pobierz google-services.json.
  3. Zauważ, że w nowym pliku konfiguracyjnym znajdują się oba identyfikatory pakietów twojego smaku
  4. Przygotuj dowolną wersję smaku.

To jest to!..

Rames Palanisamy
źródło
1
Nie jestem pewien, do czego dokładnie 2) i 3) odnoszą się. Nie mogę znaleźć nigdzie w witrynie analytics.google.com, w którym mogę dodać nazwy pakietów oprócz linku do sklepu Play. Jedyne miejsce, w którym znalazłem możliwość pobrania JSON, jest stąd developers.google.com/mobile/add , co nie pozwala na dodawanie wielu nazw pakietów. Czy będzie działać po prostu ręcznie dodając nazwy pakietów do android_client_info?
arberg
1
@arberg Możesz dodać wiele nazw pakietów do tego samego projektu, a następnie pobrać plik. Sprawdź tutaj: github.com/googlesamples/google-services/issues/54
Christer Nordvik
4

Mamy inną nazwę pakietu dla kompilacji debugowania (* .debug), więc chciałem czegoś, co działa w oparciu o flavour i buildType, bez konieczności pisania we wzorcu czegoś związanego ze smakiem processDebugFlavorGoogleServices.

W każdym smaku utworzyłem folder o nazwie „usługi Google”, zawierający zarówno wersję debugowania, jak i wersję wydania pliku json:

wprowadź opis zdjęcia tutaj

W sekcji buildTypes pliku ocen dodaj:

    applicationVariants.all { variant ->
            def buildTypeName = variant.buildType.name
            def flavorName = variant.productFlavors[0].name;

            def googleServicesJson = 'google-services.json'
            def originalPath = "src/$flavorName/google-services/$buildTypeName/$googleServicesJson"
            def destPath = "."

            copy {
                if (flavorName.equals(getCurrentFlavor()) && buildTypeName.equals(getCurrentBuildType())) {
                    println originalPath
                    from originalPath
                    println destPath
                    into destPath
                }
            }
    }

Skopiuje odpowiedni plik json w katalogu głównym modułu aplikacji automatycznie po zmianie wariantu kompilacji.

Dodaj dwie metody wywoływane, aby uzyskać bieżący smak i bieżący typ kompilacji w katalogu głównym pliku build.gradle

def getCurrentFlavor() {
    Gradle gradle = getGradle()
    String  tskReqStr = gradle.getStartParameter().getTaskRequests().toString()

    Pattern pattern;

    if( tskReqStr.contains( "assemble" ) )
        pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
    else
        pattern = Pattern.compile("generate(\\w+)(Release|Debug)")

    Matcher matcher = pattern.matcher( tskReqStr )

    if( matcher.find() ) {
        println matcher.group(1).toLowerCase()
        return matcher.group(1).toLowerCase()
    }
    else
    {
        println "NO MATCH FOUND"
        return "";
    }
}

def getCurrentBuildType() {
    Gradle gradle = getGradle()
    String  tskReqStr = gradle.getStartParameter().getTaskRequests().toString()

        if (tskReqStr.contains("Release")) {
            println "getCurrentBuildType release"
            return "release"
        }
        else if (tskReqStr.contains("Debug")) {
            println "getCurrentBuildType debug"
            return "debug"
        }

    println "NO MATCH FOUND"
    return "";
}

To wszystko, nie musisz się martwić usunięciem / dodaniem / modyfikacją smaków z pliku gradle, a automatycznie otrzyma debugowanie lub wydanie google-services.json.

FallasB
źródło
4

Firebase obsługuje teraz wiele identyfikatorów aplikacji za pomocą jednego pliku google-services.json.

Ten post na blogu szczegółowo to opisuje.

W Firebase stworzysz jeden projekt nadrzędny, którego będziesz używać dla wszystkich swoich wariantów. Następnie tworzysz osobne aplikacje na Androida w Firebase w ramach tego projektu dla każdego posiadanego identyfikatora aplikacji.

Po utworzeniu wszystkich wariantów możesz pobrać plik google-services.json, który obsługuje wszystkie identyfikatory aplikacji. Gdy istotne jest oddzielne wyświetlanie danych (tj. Raportowanie awarii), możesz przełączać je za pomocą menu rozwijanego.

bMcNees
źródło
4

Zgodnie z dokumentami Firebase zamiast google-services.json możesz również używać zasobów łańcuchowych .

Ponieważ ten dostawca tylko czyta zasoby o znanych nazwach, inną opcją jest dodanie zasobów ciągów bezpośrednio do aplikacji zamiast korzystania z wtyczki stopniowania usług Google. Możesz to zrobić przez:

  • Usuwanie google-serviceswtyczki z root build.gradle
  • Usuwanie google-services.jsonz twojego projektu
  • Bezpośrednie dodawanie zasobów ciągu
  • Usuwanie zastosowania wtyczki: 'com.google.gms.google-services'z poziomu build.gradle aplikacji

Przykład strings.xml:

<string name="google_client_id">XXXXXXXXX.apps.googleusercontent.com</string>
<string name="default_web_client_id">XXXX-XXXXXX.apps.googleusercontent.com</string>
<string name="gcm_defaultSenderId">XXXXXX</string>
<string name="google_api_key">AIzaXXXXXX</string>
<string name="google_app_id">1:XXXXXX:android:XXXXX</string>
<string name="google_crash_reporting_api_key">AIzaXXXXXXX</string>
<string name="project_id">XXXXXXX</string>
David P.
źródło
2
Miałem trudności z dopasowaniem wartości klucza w pliku google-services.json do odpowiedniego ciągu znaków, ale znalazłem to, co pomogło: developers.google.com/android/guides/... Wysłano na wypadek, gdyby ktoś miał ten sam problem.
Saifur Rahman Mohsin,
3

W oparciu o odpowiedź @ ZakTaccardi i zakładając, że nie chcesz jednego projektu dla obu smaków, dodaj to na końcu build.gradlepliku:

def appModuleRootFolder = '.'
def srcDir = 'src'
def googleServicesJson = 'google-services.json'

task switchToStaging(type: Copy) {
    outputs.upToDateWhen { false }
    def flavor = 'staging'
    description = "Switches to $flavor $googleServicesJson"
    delete "$appModuleRootFolder/$googleServicesJson"
    from "${srcDir}/$flavor/"
    include "$googleServicesJson"
    into "$appModuleRootFolder"
}

task switchToProduction(type: Copy) {
    outputs.upToDateWhen { false }
    def flavor = 'production'
    description = "Switches to $flavor $googleServicesJson"
    from "${srcDir}/$flavor/"
    include "$googleServicesJson"
    into "$appModuleRootFolder"
}

afterEvaluate {
    processStagingDebugGoogleServices.dependsOn switchToStaging
    processStagingReleaseGoogleServices.dependsOn switchToStaging
    processProductionDebugGoogleServices.dependsOn switchToProduction
    processProductionReleaseGoogleServices.dependsOn switchToProduction
}

Musisz mieć pliki src/staging/google-services.jsoni src/production/google-services.json. Zamień nazwy smaków na te, których używasz.

bryant1410
źródło
3

Odkryłem, że wtyczka usług Google jest dość bezużyteczna dla projektów, które chcą dodać GCM. Generuje tylko następujący plik, który po prostu dodaje identyfikator projektu jako zasób łańcucha:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Your API key would be on the following line -->
    <string name="gcm_defaultSenderId">111111111111</string>
</resources>

Wygląda na to, że potrzebujesz go tylko wtedy, gdy skopiowałeś przykładowy kod dosłownie bezpośrednio z przewodnika Cloud Messaging na Androida . Oto przykładowa linia:

String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),              GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

Rozwiązanie

Jeśli chcesz mieć możliwość przełączania projektów API dla różnych typów kompilacji lub smaków produktów, możesz po prostu zdefiniować własne stałe i wybrać odpowiedni podczas wywoływania getToken()API.

private static final String SENDER_ID = "111111111111";
private static final String SANDBOX_SENDER_ID = "222222222222";

String token = instanceID.getToken(
        BuildConfig.DEBUG ? SENDER_ID : SANDBOX_SENDER_ID,
        GoogleCloudMessaging.INSTANCE_ID_SCOPE,
        null);

Do smaków produktu

Powyższy kod działa przy przełączaniu między kompilacjami debugowania i wydania. W przypadku smaków produktu należy zdefiniować różne klucze API w pliku źródłowym Java i umieścić pliki w odpowiednim katalogu smaków produktu. Dla odniesienia: warianty kompilacji stopniowej

kjones
źródło
@swimmingtomars Być może niepotrzebnie stosujesz wtyczkę usługi Google. Jeśli używasz tej metody, nie możesz zastosować wtyczki usług Google. Zobacz zaakceptowaną odpowiedź, jeśli potrzebujesz tej wtyczki do usług innych niż GCM.
kjones
3

AKTUALIZACJA:

Jeśli chodzi o konfigurację Firebase z wariantami kompilacji, zapoznaj się z tym blogiem, który zawiera szczegółowe instrukcje.

KayAnn
źródło
2

Celem wtyczki usług Google jest uproszczenie integracji funkcji Google.

Ponieważ generuje tylko zasoby Androida z pliku google-services.json, myślę, że zbyt skomplikowana logika gradle neguje ten punkt.

Jeśli więc dokumenty Google nie mówią, które zasoby są potrzebne do określonych funkcji Google, sugerowałbym wygenerowanie pliku JSON dla każdego odpowiedniego typu / smaku, zobaczyć, jakie zasoby są generowane przez wtyczkę, a następnie ręcznie umieścić te zasoby do odpowiednich katalogów src / buildtypeORflavor / res.

Usuń odwołania do wtyczki usług Google i pliku JSON i gotowe.

Aby uzyskać szczegółowe informacje na temat wewnętrznego działania wtyczki stopni Google-Services, zobacz moją inną odpowiedź:

https://stackoverflow.com/a/33083898/433421

arne.jans
źródło
Nie rozumiem, w jaki sposób korzystając z Twojej odpowiedzi, mogę dołączyć 2 google-service.json. 1 do debugowania i drugi do wydania
penduDev
2

Uproszczenie tego, co powiedział @Scotti. Musisz utworzyć wiele aplikacji o różnych nazwach pakietów dla konkretnego projektu, w zależności od smaku produktu.

Załóżmy, że Twój projekt ma różne wersje produktu X, Y, gdzie X ma nazwę pakietu com.x, a Y ma nazwę pakietu com.y, a następnie w konsoli firebase musisz utworzyć projekt ABC, w którym musisz utworzyć 2 aplikacje z nazwami pakietów com.x i com.y. Następnie musisz pobrać plik google-services.json, w którym będą 2 obiekty informacji o kliencie, które będą zawierały te pacakges, i będziesz gotowy.

Fragment JSON byłby mniej więcej taki

{
  "client": [
    {
      "client_info": {
        "android_client_info": {
          "package_name": "com.x"
        }

    {
      "client_info": {
        "android_client_info": {
          "package_name": "com.y"
        }
      ]

    }
Sagar Devanga
źródło
2

Rzeczywiście, tylko jeden plik google-services.json w MyApp/app/katalogu jest dobry, nie wymaga dodatkowego skryptu z com.google.gms:google-services:3.0.0. Ale uważaj, aby usunąć plik google-services.jsonz katalogu aplikacji, MyApp/app/src/flavor1/res/aby uniknąć błęduExecution failed for task ':app:processDebugGoogleServices'. > No matching client found for package

giganty
źródło
2

Więc jeśli chcesz programowo skopiować google-services.jsonplik ze wszystkich wariantów do folderu głównego. Po przejściu na konkretny wariant znajdziesz rozwiązanie dla Ciebie

android {
  applicationVariants.all { variant ->
    copy {
        println "Switches to $variant google-services.json"
        from "src/$variant"
        include "google-services.json"
        into "."
    }
  }
}

Jest to zastrzeżenie, że musisz mieć google-service.jsonplik w każdym folderze wariantów. Oto przykład.wariant obrazu

pratham kesarkar
źródło
1

Masz wiele smaków, więc oznacza to, że będziesz mieć wiele różnych pakietów identyfikacyjnych, prawda? Więc po prostu przejdź do strony, na której konfigurujesz / generujesz plik json i konfigurujesz dla każdej nazwy pakietu. Wszystko to zostanie dodane do pliku json.

Jestem bardzo leniwy, aby opublikować zdjęcie, ale w zasadzie:

  • przejdź do https://developers.google.com/mobile/add
  • wybierz platformę
  • wybierz swoją aplikację
  • WAŻNE : wpisz nazwę pakietu smaku w polu „nazwa pakietu Androida”
  • ... kontynuuj pobieranie pliku konfiguracyjnego. Pobierz to!

Podczas konfigurowania pliku widać, że Google pokazuje klucz API serwera + identyfikator nadawcy. I to samo dla wszystkich opakowań (smaków)

Na koniec potrzebujesz tylko jednego pliku json dla wszystkich smaków.

Jeszcze jedno pytanie, które musisz sprawdzić podczas rejestracji, aby otrzymać token rejestracyjny, sprawdź, czy jest różnica dla każdego smaku. Nie dotykam tego, ale myślę, że powinna to być różnica. Za późno i jestem bardzo śpiący :) Mam nadzieję, że to pomoże!

Lạng Hoàng
źródło
1

Hej, przyjaciele szukają również nazwy używanej tylko małymi literami, więc nie pojawia się ten błąd

Divyesh Jani
źródło
0

Obecnie używam dwóch identyfikatorów projektu GCM w tym samym pakiecie aplikacji. Umieszczam plik google-service.json mojego pierwszego projektu GCM, ale przełączam się z pierwszego na drugi, zmieniając tylko SENDER_ID:

    String token = instanceID.getToken(SENDER_ID,GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

(W tym momencie myślę, że plik google-services.json nie jest obowiązkowy)

ariostoi
źródło
0

Zainspirowany powyższą odpowiedzią @ ahmed_khan_89. Możemy tak bezpośrednio przechowywać w pliku gradle.

android{

// set build flavor here to get the right Google-services configuration(Google Analytics).
    def currentFlavor = "free" //This should match with Build Variant selection. free/paidFull/paidBasic

    println "--> $currentFlavor copy!"
    copy {
        from "src/$currentFlavor/"
        include 'google-services.json'
        into '.'
    }
//other stuff
}
Noundla Sandeep
źródło
0

Umieść plik „google-services.json” odpowiednio w app / src / flavours, a następnie w build.gradle aplikacji, pod Android dodaj poniższy kod

gradle.taskGraph.beforeTask { Task task ->
        if (task.name ==~ /process.*GoogleServices/) {
            android.applicationVariants.all { variant ->
                if (task.name ==~ /(?i)process${variant.name}GoogleServices/) {
                    copy {
                        from "/src/${variant.flavorName}"
                        into '.'
                        include 'google-services.json'
                    }
                }
            }
        }
    }
Sameer Khader
źródło