Google-services.json для разных продуктовFlavors
Update: GCM is deprecated, use FCM
Я внедряю новый Google Cloud Messaging, следуя инструкциям на странице разработчиков Google здесь
Я успешно запустил и протестировал его. Но моя проблема сейчас в том, что у меня разные варианты продукта с разными applicationId/packageName и разными идентификаторами проекта Google Cloud Messaging Project. google-services.json
должен быть помещен в /app/google-services.json
, а не в папку flavors.
Есть ли способ сделать конфиг google-services.json
разным для разных вкусов?
Ответы
Ответ 1
Google включил поддержку ароматов в версию 2.0 плагина сервисов воспроизведения. Начиная с этой версии 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
flav1 и тип сборки debug
):
/app/src/debug/google-services.json
/app/src/debug/flavor1/google-services.json
/app/google-services.json
Это сработало для меня даже с использованием flavourDimensions. У меня есть бесплатные & оплачивается в одном измерении и макет & Прод в другом измерении. У меня также есть 3 buildTypes: отладка, выпуск и постановка. Вот как это выглядит в моем проекте для аромата FreeProd:
![enter image description here]()
Сколько файлов google-services.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
Ответ 2
ОБНОВЛЕНИЕ: Ниже приведено объяснение для одного проекта Android Studio с одним проектом Firebase и различными Firebase Apps внутри этого проекта.
Если цель состоит в том, чтобы иметь разные файлы JSON для разных приложений Firebase в разных проектах Firebase внутри одного и того же проекта Android Studio (или если вы не знаете, в чем разница) смотрите здесь.
Вам нужно одно приложение Firebase для Android-приложения (обычно это имя пакета). Обычно имеет один идентификатор приложения для варианта сборки Gradle (это будет вероятно, если вы используете типы сборки Gradle и Gradle).
Как и в Google Services 3.0 и используя Firebase, нет необходимости создавать разные файлы для разных вкусов. Создание разных файлов для разных вкусов может быть непонятным или простым в том случае, если у вас есть productFlavours и типы сборки, которые составляют друг с другом.
В том же файле вы будете иметь все конфигурации, необходимые для всех типов сборки и вкусов.
В консоли Firebase вам нужно добавить одно приложение для имени пакета. Представьте, что у вас есть 2 аромата (dev и live) и 2 типа сборки (отладка и выпуск). В зависимости от вашей конфигурации, но, вероятно, у вас есть 4 разных имени пакета, например:
- com.stackoverflow.example(live-release)
- com.stackoverflow.example.dev(live-dev)
- com.stackoverflow.example.debug(debug-release)
- com.stackoverflow.example.dev.debug(debug-dev)
Вам нужно 4 различных приложения для Android в Firebase Console. (Для каждого из них вам нужно добавить SHA-1 для отладки и жить для каждого компьютера, который вы используете)
Когда вы загружаете файл google-services.json, на самом деле это не имеет никакого значения, из какого приложения вы его загружаете, все они содержат одну и ту же информацию, связанную со всеми вашими приложениями.
Теперь вам нужно найти этот файл на уровне приложения (app/).
![введите описание изображения здесь]()
Если вы откроете этот файл, вы увидите, что if содержит всю информацию для всех ваших имен пакетов.
Больной точкой является плагин. Чтобы получить работу, вам нужно найти плагин в нижней части файла. Итак, эта строка..
apply plugin: 'com.google.gms.google-services'
... должен быть в нижней части вашего файла build.gradle приложения.
Для большей части сказанного здесь это относится и к предыдущим версиям. У меня никогда не было разных файлов для разных конфигураций, но теперь с консолью Firebase проще, потому что они предоставляют один файл со всем, что вам нужно для всех ваших конфигураций.
Ответ 3
Написал средний пост по этой проблеме.
Если бы подобная проблема (с использованием BuildTypes вместо Flavors) и исправлена так.
Воспользуйтесь системой управления зависимостями 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
}
РЕДАКТИРОВАТЬ: используйте задачу processDebugFlavorGoogleServices
/processReleaseFlavorGoogleServices
, чтобы изменить ее на уровне каждого уровня.
Ответ 4
Ну, я столкнулся с той же проблемой и не смог найти идеального решения. Это просто обходной путь.
Мне интересно, как Google не думал о вкусах...? И я надеюсь, что они вскоре предложит лучшее решение.
Что я делаю:
У меня есть два варианта: в каждом я помещаю соответствующие google-services.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
close... не смог найти лучшего решения до сих пор.
Обновление, другое решение: один google-services.json для всех вариантов:
Вы также можете иметь разные имена пакетов для каждого аромата, а затем в консоли разработчика Google вам не нужно создавать два разных приложения для каждого аромата, но только два разных клиента в одном приложении.
Тогда у вас будет только один google-services.json
, содержащий ваших обоих клиентов.
Конечно, это зависит от того, как вы реализуете бэкэнд своих вкусов. Если они не разделены, это решение вам не поможет.
Ответ 5
В соответствии с ответом 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 '.'
}
}
}
Затем вам не нужно вручную переключаться с настройками.
Ответ 6
Файл google-services.json не требуется для получения уведомлений. Просто добавьте переменную для каждого аромата в файле build.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);
Ответ 7
Я использую файл google-services.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-данные. Я не смог правильно отформатировать его...
Ответ 8
1.) Что делает google-services.json действительно?
Следуйте этому следующему: fooobar.com/questions/39666/...
2.) Как файл google-services.json влияет на ваш проект студии Android?
Следуйте этому: fooobar.com/questions/39666/...
вкратце для второго URL-адреса, если вы добавите google-services.json в свой проект, в этом пути должна быть создана сгенерированная автоматически google-services
папка для debug
.
app/build/generated/res/google-services/debug/values/values.xml
3.) Что делать, чтобы сделать это?
добавьте зависимость google-services в project_level
build.gradle, вы также можете использовать version 3.0.0
, если используете библиотеку app_compact.
// Top-level build.gradle file
classpath 'com.google.gms:google-services:2.1.2'
теперь в app_level
build.gradle вы должны добавить внизу.
// app-level build.gradle file
apply plugin: 'com.google.gms.google-services'
4.) Куда поместить файл google-service.json в вашу структуру.
case 1.), если у вас нет build_flavor, просто поместите его внутри папки /app/google-service.json
.
case 2.), если у вас есть несколько build_flavor, и у вас есть разные файлы google_services.json, помещенные внутри app/src/build_flavor/google-service.json
.
case 3.), если у вас есть несколько build_flavor, и у вас есть один файл google_services.json, помещенный внутри app/google-service.json
.
Ответ 9
ОБНОВЛЕНО:
С точки зрения настройки Firebase с вариантами сборки, пожалуйста, обратитесь к этому блогу, в котором есть подробные инструкции.
Ответ 10
У нас есть другое имя пакета для отладочных сборников (*.debug), поэтому я хотел что-то, что работает на основе flavor и buildType, без необходимости писать что-либо, связанное с ароматом, в шаблоне processDebugFlavorGoogleServices
.
В каждом аромате я создал папку с именем "google-services", содержащую как версию отладки, так и версию выпуска json файла:
![введите описание изображения здесь]()
В разделе 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 файл в корень вашего модуля приложения, когда вы переключите вариант сборки.
Добавьте два метода, которые вызывают, чтобы получить текущий тип и текущий тип сборки в корне вашего 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 "";
}
Для этого вам не нужно беспокоиться об удалении/добавлении/изменении вкусов из вашего файла gradle, и он автоматически отлаживает или выпускает google-services.json.
Ответ 11
Firebase теперь поддерживает несколько идентификаторов приложений с одним файлом google-services.json.
Это сообщение в блоге подробно описывает его.
Вы создадите один родительский проект в Firebase, который вы будете использовать для всех ваших вариантов. Затем вы создаете отдельные приложения для Android в Firebase в рамках этого проекта для каждого вашего идентификатора приложения.
Когда вы создали все свои варианты, вы можете загрузить google-services.json, который поддерживает все ваши идентификаторы приложений. Когда это имеет значение для просмотра данных отдельно (т.е. Crash Reporting), вы можете переключаться с раскрывающимся списком.
Ответ 12
Основываясь на ответе @ZakTaccardi и предполагая, что вам не нужен один проект для обоих вариантов, добавьте его в конец вашего файла build.gradle
:
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
. Замените имена аромата для тех, которые вы используете.
Ответ 13
Я обнаружил, что плагин google-services совершенно бесполезен для проектов, которые хотят добавить 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 Messaging for Android. Вот пример строки:
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
Решение
Если вы хотите иметь возможность переключать проекты API для разных типов сборки или продуктов, вы можете просто определить свои собственные константы и выбрать подходящий при вызове API getToken()
.
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);
Для ароматов продукта
Приведенный выше код работает для переключения между сборками отладки и выпуска. Для вкусов продукта вы должны определить разные ключи API в исходном файле java и поместить файлы в соответствующий каталог продуктов. Для справки: Gradle Варианты сборки
Ответ 14
Нет необходимости в дополнительных скриптах gradle.
Google начал добавлять разные имена пакетов под именем "android_client_info". Он выглядит ниже в google-services.json
"android_client_info": {
"package_name": "com.android.app.companion.dev"
}
поэтому для выполнения разных вариантов google-services.json достаточно выполнить следующие шаги.
- Есть 2 аромата
- Добавьте новый пакет аромата dev на страницу конфигурации Google Analytics и загрузите google-services.json.
- Обратите внимание, что в новом файле конфигурации есть оба идентификатора пакета аромата.
- Подготовьте любой из ваших ароматов.
Вот и все!..
Ответ 15
Точка плагина google-services предназначена для упрощения интеграции функций Google.
Поскольку он генерирует только андроидные ресурсы из файла google-services.json, чрезмерный сложный gradle -logic отрицает этот момент, я думаю.
Итак, если Google-документы не говорят, какие ресурсы необходимы для определенных функций Google, я бы предложил создать JSON файл для каждого соответствующего типа buildtype/flavor, посмотреть, какие ресурсы будут генерироваться плагином, а затем разместить эти ресурсы вручную в соответствующие каталоги src/buildtypeORflavor/res.
После этого удалите ссылки на плагин google-services и JSON файл, и все готово.
Для получения подробной информации о внутренней работе google-services gradle -plugin см. мой другой ответ:
fooobar.com/questions/39666/...
Ответ 16
Упрощение того, что сказал @Scotti. Вам необходимо создать приложения Multiples с различным именем пакета для конкретного проекта в зависимости от вкуса продукта.
Предположим, что у вашего проекта есть ABC с разными вкусами продукта X, Y, где X имеет имя пакета com.x, а Y имеет имя пакета com.y, тогда в консоли firebase вам необходимо создать проект ABC, в котором вам нужно создать 2 приложения с именами пакетов com.x и com.y. Затем вам нужно загрузить файл google-services.json, в котором будет два объекта-клиент-информация, которые будут содержать эти pacakges, и вам будет хорошо идти.
Фрагмент json будет примерно таким
{
"client": [
{
"client_info": {
"android_client_info": {
"package_name": "com.x"
}
{
"client_info": {
"android_client_info": {
"package_name": "com.y"
}
]
}
Ответ 17
У вас много вкуса, так что это означает, что у вас будет много разного идентификатора пакета, верно? Итак, просто зайдите на страницу, где вы настраиваете/генерируете свой json файл и конфигурацию для каждого имени пакета. Все это добавит json файл.
Теперь я не буду лениво размещать картинку, но в основном:
- перейти к https://developers.google.com/mobile/add
- выберите платформу
- выберите ваше приложение.
- ВАЖНО: введите имя пакета аромата в поле "имя пакета Android"
- ... продолжаем получать ваш файл конфигурации. Загрузите его!
При настройке файла вы увидите, что Google показывает вам идентификатор сервера + идентификатор отправителя. И он одинаковый для всех пакетов (ароматов)
В конце вам нужен всего один файл json для всех вкусов.
Еще один вопрос, который вы должны проверить, когда регистрируетесь, чтобы получить регистрационный токен, проверьте, есть ли разница для каждого аромата. Я не касаюсь этого, но думаю, что это должно быть различие. Слишком поздно, и я так сонный:) Надеюсь, это поможет!
Ответ 18
Привет, друзья также ищут использование имени только в нижнем регистре, тогда вы не получите эту ошибку
Ответ 19
Действительно, juste one google-services.json в каталоге MyApp/app/
хорош, нет необходимости в дополнительном script с 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
Ответ 20
Так что если вы хотите программно скопировать файл google-services.json
из всех ваших вариантов в вашу корневую папку. Когда вы переключаетесь на конкретный вариант, здесь решение для вас
android {
applicationVariants.all { variant ->
copy {
println "Switches to $variant google-services.json"
from "src/$variant"
include "google-services.json"
into "."
}
}
}
Есть предостережение в отношении этого подхода: вам нужно иметь файл google-service.json
в каждой папке с вариантами, вот пример. ![variant image]()
Ответ 21
В настоящее время я использую два идентификатора проекта GCM в том же пакете приложений. Я поместил google-service.json из моего первого проекта GCM, но переключился с первого на второй, только меняя SENDER_ID:
String token = instanceID.getToken(SENDER_ID,GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
(В этот момент я думаю, что google-services.json не является обязательным)
Ответ 22
Вдохновленный @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
}
Ответ 23
Поместите файл "google-services.json" в папку app/src/flavors соответственно
затем в build.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'
}
}
}
}
}
Ответ 24
Согласно Документам Firebase вы также можете использовать строковые ресурсы вместо google-services.json.
Поскольку этот поставщик просто читает ресурсы с известными именами, другой вариант заключается в добавлении строковых ресурсов непосредственно в ваше приложение вместо использования подключаемого модуля Google Services. Вы можете сделать это:
- Удаление плагина
google-services
из корневого каталога build.gradle
- Удаление
google-services.json
из вашего проекта
- Добавление строковых ресурсов напрямую
- Удаление подключаемого модуля:
'com.google.gms.google-services'
из вашего приложения build.gradle
Пример 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>
Ответ 25
Здравствуйте! google.com Попробуйте поискать в Google, это поможет!