it-swarm.com.ru

google-services.json для разных продуктовFlavors

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

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

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

Есть ли способ сделать конфигурацию google-services.json разной для многих разновидностей?

405
gentra

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

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

enter image description here

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

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

Ссылка на официальные документы: 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

454
Yair Kukielka

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

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


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

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

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

  • com.stackoverflow.example (live - release)
  • com.stackoverflow.example.dev (live - dev)
  • com.stackoverflow.example.debug (отладка - выпуск)
  • com.stackoverflow.example.dev.debug (debug - dev)

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

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

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

enter image description here

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

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

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

... должен быть в нижней части файла вашего приложения build.gradle.

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

54
Sotti

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

Возникла похожая проблема (с использованием 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, чтобы изменить ее на уровне вкуса.

38
ZakTaccardi

Согласно ответу 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 '.'
        }
    }
}

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

12
Kros C.S. Huang

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

Что я делаю:

У меня есть два варианта, в каждый из которых я добавляю соответствующий google-services.json: src/flavor1/google-services.json и src/flavor2/google-services.json.

Затем в сборке сборки я копирую файл в зависимости от разновидности в каталог 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, содержащий оба ваших клиента. Конечно, это зависит от того, как вы реализуете бэкэнд своих вкусов. Если они не разделены, то это решение вам не поможет.

12
ahmed_khan_89

Я использую файл google-services.json, созданный здесь: https://developers.google.com/mobile/add?platform=Android&cntapi=gcm&cnturl=https:%2F%2Fdevelopers.google.com % 2Fcloud-сообщения% 2Fandroid% 2Fclient & cntlbl = Продолжить% 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-data.

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

8
Mark Martinsson

файл 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);
8
divonas

1.) Что на самом деле делает google-services.json?

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

2.) Как файл google-services.json влияет на ваш Android студийный проект?

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

вкратце, для второго 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 в вашей структуре.

случай 1.) если у вас нет build_flavor, просто поместите его в папку /app/google-service.json.

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

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

5
Tushar Pandey

У нас есть другое имя пакета для отладочных сборок (* .debug), поэтому я хотел что-то, что работает на основе flavour и 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 в корень вашего модуля приложения.

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

4
FallasB

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

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

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

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

4
bMcNees

ОБНОВЛЕНО:

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

3
KayAnn

Основываясь на ответе @ 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. Замените названия вкусов на те, которые вы используете.

3
bryant1410

Не нужно никаких дополнительных скриптов.

Google начал добавлять другое имя пакета в имя "Android_client_info". Это выглядит ниже в google-services.json

"Android_client_info": {
      "package_name": "com.Android.app.companion.dev"
    }

поэтому для выбора другого google-services.json достаточно следующих шагов.

  1. Есть 2 вкуса
  2. Добавьте новый пакет dev flavour на страницу конфигурации Google Analystics и загрузите google-services.json.
  3. Обратите внимание, в новом файле конфигурации оба идентификатора пакета вашего вкуса есть
  4. Подготовьте любой свой вкус сборки.

Вот и все! ..

3
Rames Palanisamy

Я обнаружил, что плагин 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

3
kjones

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

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

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

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

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

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

2
arne.jans

Упрощение того, что сказал Скотти. Вам необходимо создавать приложения Multiples с разными именами пакетов для конкретного проекта в зависимости от вкуса продукта.

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

Фрагмент JSON будет что-то вроде этого

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

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

    }
2
Sagar Devanga

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

1
Divyesh Jani

Действительно, использовать один google-services.json в каталоге MyApp/app/ хорошо, нет необходимости в дополнительном скрипте с 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

1
gigeos

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

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

  • перейдите на страницу https://developers.google.com/mobile/add
  • выберите платформу
  • выберите ваше приложение
  • ВАЖНО: введите имя вашего пакета ароматизаторов в поле "Имя пакета Android"
  • ... продолжить получать ваш файл конфигурации. Загрузить!

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

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

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

1
Lạng Hoàng

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

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

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

0
ariostoi

Поместите файл "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'
                    }
                }
            }
        }
    }
0
Sameer Khader

Вдохновленный ответом @ 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
}
0
Noundla Sandeep