службы Google.json для различных productFlavors

обновление: GCM устарел, используйте FCM

я внедряю новый Google Cloud Messaging, следуя руководствам со страницы разработчиков Google здесь

Я успешно запустил и протестировал его. Но моя проблема теперь в том, что у меня разные productFlavors с разным applicationId/packageName и другим идентификатором проекта GCM. The google-services.json должны быть помещены в тег /app/google-services.json Не ароматы папка.

есть ли способ сделать google-services.json config отличается для многих вкусов?

22 ответов


Google включил поддержку вкусов в версии 2.0 плагина play services. Начиная с этой версии gradle plugin com.google.gms:google-services:2.0.0-alpha3

вы можете сделать это

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

версия 3.0.0 плагина ищет файл JSON в этих местах (учитывая, что у вас есть flavor flavor1 и тип сборки debug):

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

это сработало для меня даже с использованием flavorDimensions. У меня есть free & paid в одном измерении и Mock & Prod в другом измерении. У меня тоже 3 buildTypes: отладка, выпуск и постановка. Вот как это выглядит в моем проекте для вкуса FreeProd:

enter image description here

сколько google-сервисов.файлы json будут зависеть от характеристик вашего проекта, но вам понадобится по крайней мере один файл json для каждого проекта Google.

если вы хотите получить более подробную информацию о том, что этот плагин делает с этими файлами json, вот он есть: https://github.com/googlesamples/google-services/issues/54#issuecomment-165824720

ссылка на официальные документы: https://developers.google.com/android/guides/google-services-plugin

сообщение в блоге с обновленной информацией: https://firebase.googleblog.com/2016/08/organizing-your-firebase-enabled-android-app-builds.html

и заходите сюда, чтобы проверить последнюю версию этого плагина: https://bintray.com/android/android-tools/com.google.gms.google-services/view


обновление: следующее объяснение для одного проекта Android Studio, с одним проектом Firebase и различными приложениями Firebase внутри этого проекта. Если цель состоит в том, чтобы иметь разные файлы JSON для разных приложений Firebase в разных проектах Firebase внутри одного и того же проекта Android Studio, (или если вы не знаете, в чем разница) посмотреть здесь..

вам нужно одно приложение Firebase на идентификатор приложения Android (обычно имя пакета). Часто один идентификатор приложения для варианта сборки Gradle (это будет вероятно, если вы используете типы сборки Gradle и ароматы сборки Gradle)


по состоянию на Google Services 3.0 и с помощью Firebase не нужно создавать разные файлы для разных вкусов. Создание разных файлов для разных вкусов может быть неясным или простым, если у вас есть productFlavours и типы сборки, которые составляют друг с другом.

в том же файле у вас будут все необходимые конфигурации для всех типов сборки и вкусов.

в консоли Firebase вам нужно добавить одно приложение на имя пакета. Представьте, что у вас есть 2 вкуса (dev и live) и 2 типа сборки (debug и release). В зависимости от вашей конфигурации, но, вероятно, у вас есть 4 разных имени пакета, таких как:

  • com.сайте StackOverflow.пример (live - release)
  • com.сайте StackOverflow.образец.dev (live - dev)
  • com.сайте StackOverflow.образец.debug (debug - release)
  • com.сайте StackOverflow.образец.разработка.debug (debug - dev)

вам нужно 4 различных приложения для Android в консоли Firebase. (На каждом вам нужно добавить SHA-1 для отладки и жить для каждого компьютера, который вы используете)

при загрузке Google-сервисов.файл json, на самом деле это не имеет значения, из какого приложения вы его загружаете, все они содержат одинаковую информацию, связанную со всеми ваши приложения.

теперь вам нужно найти этот файл на уровне приложения (app/).

enter image description here

Если вы откроете этот файл, вы увидите, что if содержит всю информацию для всех ваших имен пакетов.

точка боли используется в качестве плагина. Для того, чтобы заставить его работать вам нужно найти плагин в нижней части вашего файла. Итак, эта линия..

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

...должно быть в нижней части сборки приложения.Gradle в файл.

для большей части сказанного здесь, это относится и к предыдущим версиям. У меня никогда не было разных файлов для разных конфигураций, но теперь с консолью Firebase проще, потому что они предоставляют один файл со всем, что вам нужно для всех конфигураций.


написал средний пост по этому вопросу.

имел аналогичную проблему (используя BuildTypes вместо ароматов) и исправил ее так.

воспользуйтесь системой управления зависимостями Gradle. Я создал две задачи, switchToDebug и switchToRelease. Требуйте этого в любое время assembleRelease запускается, что switchToRelease тоже работать. То же самое для отладки.

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
}

EDIT: использовать processDebugFlavorGoogleServices/processReleaseFlavorGoogleServices задача изменить его на уровне вкуса.


Ну, я сталкиваюсь с той же проблемой и не могу получить идеальное решение. Это просто обходной путь. Мне интересно, как Google не думал о вкусах...? И я надеюсь, что скоро они предложат лучшее решение.

что я делаю:

у меня два вкуса, в каждом я ставлю соответствующие Google-сервисы.в JSON : src/flavor1/google-services.json и src/flavor2/google-services.json .

затем в build gradle я копирую файл в зависимости от вкуса в app/ каталог:

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
}

ограничения: вам придется менять myFlavor вручную в gradle каждый раз, когда вы хотите работать для другого вкуса (потому что он жестко закодирован).

Я пробовал много способов получить текущий вкус сборки, как afterEvaluate закрыть... до сих пор не было лучшего решения.

обновление, другое решение: один google-services.json для всех вкусов:

вы можете также, иметь различные названия пакетов для каждого вкуса, а затем в консоль разработчика google вам не нужно создавать два разных приложения для каждого вкуса, но только два разных клиента в одном приложении. Тогда у вас будет только один google-services.json который содержит обоих ваших клиентов. Конечно, это зависит от того, как вы реализуете бэкэнд вашего вкуса. Если они не разделены, то это решение не поможет вам.


по данным ahmed_khan_89ответ, вы можете положить вас "код экземпляра" внутри вкусов продукта.

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 '.'
        }
    }
}

тогда вам не нужно переключать настройки вручную.


google-сервисы.файл json не нужен для получения уведомлений. Просто добавьте переменную для каждого вкуса в вашей сборке.файл gradle:

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

используйте эту переменную BuildConfig.GCM_SENDER_ID вместо getString (R. string.gcm_defaultSenderId) при регистрации:

instanceID.getToken(BuildConfig.GCM_SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

Я использую Google-сервисы.файл json, созданный отсюда: https://developers.google.com/mobile/add?platform=android&cntapi=gcm&cnturl=https:%2F%2Fdevelopers.google.com%2Fcloud-messaging%2Fandroid%2Fclient&cntlbl=Continue%20Adding%20GCM%20Support&%3Fconfigured%3Dtrue

в JSON-структуре есть JSON-массив, называемый клиентами. Если у вас есть несколько вкусов, просто добавьте сюда различные свойства.

{
  "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"
}

в моем проекте я использую тот же идентификатор проекта, и когда я добавляю второе имя пакета в вышеуказанный url, google предоставляет мне файл, содержащий несколько клиентов в JSON-данных.

извините за компактные JSON-данные. Я не смог правильно отформатировать его...


У нас есть другое имя пакета для отладочных сборок (*.debug), поэтому я хотел что-то, что работает на основе flavor и buildType, без необходимости писать что-либо, связанное с ароматом, в шаблоне processDebugFlavorGoogleServices.

Я создал папку с именем "google-services" в каждом вкусе, содержащую как отладочную версию, так и версию выпуска файла json :

enter image description here

В разделе buildTypes вашего файла gradle добавьте это :

    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
                }
            }
    }

он автоматически скопирует правильный файл json в корне вашего модуля приложения, когда вы переключите вариант сборки.

добавьте два метода, вызываемые для получения текущего вкуса и текущего типа сборки в корне вашей сборки.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 "";
}

вот и все, вам не нужно беспокоиться об удалении/добавлении/изменении ароматов из вашего файла gradle, и он получит отладку или выпуск google-сервисов.в JSON автоматически.


Firebase теперь поддерживает несколько идентификаторов приложений с одним google-services.файл json.

этот блог описывает его подробно.

вы создадите один родительский проект в Firebase, который вы будете использовать для всех своих вариантов. Затем вы создаете отдельные приложения Android в Firebase в рамках этого проекта для каждого идентификатора приложения, который у вас есть.

когда вы создали все свои варианты, вы можете скачать google-services.JSON, который поддерживает все ваши идентификаторы приложений. Когда важно видеть данные отдельно (т. е. отчеты о сбоях), вы можете переключить это с помощью раскрывающегося списка.


основываясь на ответе @ZakTaccardi и предполагая, что вам не нужен один проект для обоих вкусов, добавьте это в конец вашего :

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
}

вы должны иметь файлы src/staging/google-services.json и src/production/google-services.json. Замените названия вкусов на те, которые вы используете.


я обнаружил, что google-услуги плагин совершенно бесполезен для проектов, которые хотят добавить GCM. Он генерирует только следующий файл, который просто добавляет Ваш идентификатор проекта в качестве строкового ресурса:

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

похоже, что вам это нужно, только если вы скопировали образец кода дословно непосредственно из Cloud сообщениями для Android руководство. Вот пример:

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

решение

если вы хотите иметь возможность переключаться Проекты API для различных типов сборки или вкусов продукта вы можете просто определить свои собственные константы и выбрать подходящий при вызове 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);

Для Вкусов Продукта

приведенный выше код работает для переключения между Debug и Release строит. Для вкусов продукта вы бы определили различные ключи API в исходном файле java и разместили файлы в соответствующем каталоге вкуса продукта. Для справки: Сборка Gradle Варианты


нет необходимости в каких-либо дополнительных скриптах gradle.

Google начал добавлять другое имя пакета с именем "android_client_info". Это выглядит как ниже в google-сервисах.в JSON

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

Итак, следующих шагов достаточно, чтобы иметь разные сервисы google.выбор json.

  1. есть 2 кухни
  2. добавьте новый пакет dev flavour на страницу конфигурации google analystics и загрузите google-сервисы.формат JSON.
  3. уведомления в новый файл конфигурации, оба идентификатора пакета вашего вкуса есть
  4. подготовьте любой из ваших ароматов.

вот оно!..


1.) что делает google-services.в JSON действительно?

следуйте этому : https://stackoverflow.com/a/31598587/2382964

2.) как работает google-services.файл json влияет на ваш проект Android studio?

следуйте этому : https://stackoverflow.com/a/33083898/2382964

просто вкратце для второго url, если вы добавляете google-services.JSON в вашем проекте должен быть автоматически генерируется на debug вариант в этом пути

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

3.) что делать,чтобы сделать это?

добавить зависимость google-services в project_level построить.Gradle, вы также можете использовать version 3.0.0 если вы используете библиотеку app_compact.

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

сейчас app_level построить.gradle вы должны добавить в нижней части.

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

4.) куда поставить google-сервис.файл json в вашем структура.

корпус 1.) если у вас нет build_flavor просто поместите его внутрь .

корпус 2.) если у вас несколько build_flavor и у вас разные-разные google_services.файлы JSON положить внутрь app/src/build_flavor/google-service.json.

корпус 3.) если у вас есть несколько build_flavor и у вас есть один google_services.файл json помещен внутрь app/google-service.json.


суть плагина google-services заключается в упрощении интеграции функций Google.

поскольку он генерирует только android-ресурсы из google-сервисов.файл json, слишком сложная логика gradle отрицает этот момент, я думаю.

поэтому, если Google-docs не говорят, какие ресурсы необходимы для определенных функций Google, я бы предложил создать JSON-файл для каждого соответствующего buildtype/ flavor, посмотреть, какие ресурсы генерируются плагином, а затем поместить эти ресурсы вручную в соответствующие каталоги src/buildtypeORflavor/res.

удалите ссылки на плагин google-services и JSON-файл после этого, и все готово.

для получения подробной информации о внутренней работе google-services gradle-plugin см. Мой другой ответ:

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


упрощение того, что сказал @Scotti. Вам нужно создать несколько приложений с разными именами пакетов для конкретного проекта в зависимости от вкуса продукта.

предположим, что ваш проект ABC имеет разные вкусы продукта X, Y, где X имеет имя пакета com.x и Y имеют имя пакета com.y затем в консоли firebase вам нужно создать проект ABC, в котором вам нужно создать 2 приложения с именами пакетов com.x и com.y. Затем необходимо скачать google-сервисы.формат JSON файл, в котором будет 2 объекта client-info, которые будут содержать эти pacakges, и вам будет хорошо идти.

фрагмент json будет чем-то вроде этого

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

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

    }

У вас много вкуса, так что это означает, что у вас будет много ID пакета разницы, верно? Итак, просто перейдите на страницу, где вы устанавливаете/генерируете файл json и конфигурацию для каждого имени пакета. Все это добавит в файл json.

Я очень ленив, чтобы опубликовать изображение сейчас, но в основном:

  • на https://developers.google.com/mobile/add
  • выберите platform
  • выберите приложение
  • важно: тип ваш вкус имя пакета в поле "android имя пакета"
  • ... продолжайте получать файл конфигурации. Скачать его!

при настройке файла вы можете увидеть, что google показывает вам ключ API сервера + идентификатор отправителя. И это же для всех пакетов (вкусов)

в конце вам просто нужен только один файл json для всех вкусов.

еще один вопрос здесь, который вы должны проверить при регистрации, чтобы получить регистрационный токен, проверьте, есть ли разница для каждый вкус. Я не касаюсь этого, но думаю, что должна быть разница. Слишком поздно, и я так сонный:) надеюсь, это поможет!


Эй друзья также ищет имя использовать только в нижнем регистре, то и не получить эту ошибку


обновление:

с точки зрения установки Firebase с вариантами сборки, пожалуйста, обратитесь к этот блог который имеет подробные инструкции.


в настоящее время я использую два идентификатора проекта GCM в одном пакете приложений. Я поставил google-сервис.json моего первого проекта GCM, но я переключаюсь с первого на второй, только изменяя SENDER_ID:

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

(на данный момент я думаю, что google-сервисы.json не является обязательным)


вдохновленный ответом @ahmed_khan_89 выше. Мы можем напрямую сохранить это в файле 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
}

разместите свои "google-сервисы".файл "json" под app/src/flavors соответственно затем в сборке.gradle приложения, под android добавить ниже кода

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'
                    }
                }
            }
        }
    }

действительно, только один google-услуги.json in MyApp/app/ каталог хорош, нет необходимости в aditional скрипте с com.google.gms:google-services:3.0.0. Но будьте осторожны, чтобы удалить файл google-services.json из каталога приложений MyApp/app/src/flavor1/res/ чтобы избежать ошибки типа Execution failed for task ':app:processDebugGoogleServices'. > No matching client found for package