Google Developersページのガイドに従って、新しいGoogle Cloud Messagingを実装しています ここ
実行してテストしました。しかし、今私の問題は、異なるapplicationId/packageNameと異なるGoogle Cloud MessagingプロジェクトIDを持つ異なる製品フレーバーがあることです。 google-services.json
はフレーバーフォルダーではなく/app/google-services.json
に配置する必要があります。
多くのフレーバーでgoogle-services.json
設定を異なるものにする方法はありますか?
Googleは、play servicesプラグインのバージョン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
フレーバー1およびビルドタイプ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を使っても私のために働きました。私は一方の次元で無料で支払い、もう一方の次元でMock&Prodを支払いました。デバッグ、リリース、ステージングという3つのbuildTypeもあります。これが私のプロジェクトのFreeProdフレーバーの見方です。
Google-services.jsonファイルの数はプロジェクトの特性によって異なりますが、Googleプロジェクトごとに少なくとも1つのjsonファイルが必要です。
このプラグインがこれらの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
更新: 以下の説明は、1つのFirebaseプロジェクトとそのプロジェクト内の異なるFirebaseアプリケーションを含む、1つのAndroid Studioプロジェクト用です。目的が、同じAndroid Studioプロジェクト内の異なるFirebaseプロジェクトの異なるFirebaseアプリケーション用に異なるJSONファイルを作成することである場合(または、違いがわからない場合) ここを見てください。 。
AndroidアプリケーションIDごとに1つのFirebase Appが必要です(通常はパッケージ名)。 Gradleビルドバリアントごとに1つのアプリケーションIDを持つのが一般的です(これは、GradleビルドタイプとGradleビルドフレーバーを使用する場合に起こりそうです)。
Google Services 3.0 および Firebase の時点では、さまざまな種類のファイルを別々に作成する必要はありません。異なるフレーバー用に異なるファイルを作成することは、お互いに構成されているproductFlavoursとBuildタイプがある場合、明確ではないか単純明快ではありません。
同じファイルに、すべてのビルドタイプとフレーバーに必要なすべての設定があります。
Firebase consoleでは、パッケージ名ごとに1つのアプリを追加する必要があります。 2つのフレーバー(devとlive)と2つのビルドタイプ(debugとrelease)があると想像してください。設定にもよりますが、4つの異なるパッケージ名がある可能性があります。
Firebase Consoleには4つの異なるAndroidアプリが必要です。 (それぞれに、デバッグ用にSHA-1を追加し、使用している各コンピュータに対応する必要があります)
Google-services.jsonファイルをダウンロードしても、実際にはどのアプリをダウンロードしても問題ありません。すべてのアプリに同じ情報が含まれています。
今、あなたはアプリレベル(app /)でこのファイルを見つける必要があります。
そのファイルを開くと、すべてのパッケージ名に関するすべての情報が含まれていることがわかります。
問題点は、プラグインになることです。それを機能させるためには、あなたのファイルの一番下にプラグインを配置する必要があります。だからこの行..
apply plugin: 'com.google.gms.google-services'
...あなたのアプリのbuild.gradleファイルの一番下にある必要があります。
ここで述べたことのほとんどについては、それは以前のバージョンにも適用されます。設定ごとに異なるファイルを作成したことは一度もありませんが、Firebase consoleでは、すべての設定に必要なものがすべて1つのファイルにまとめられているので、簡単になりました。
この問題について 中程度の投稿 を書きました。
(Flavorsの代わりにBuildTypesを使用して)同様の問題を抱えていて、そのように修正しました。
Gradleの依存管理システムを利用してください。 switchToDebug
とswitchToRelease
の2つのタスクを作成しました。 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
タスクを使用して、フレーバーごとのレベルで変更します。
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 '.'
}
}
}
その後、設定を手動で切り替える必要はありません。
まあ私は同じ問題に遭遇していて、どんな完璧な解決策も得られませんでした。これは単なる回避策です。グーグルがどのようにフレーバーについて考えなかったのかと思っています…?そして私は彼らがすぐにもっと良い解決策を提案することを願っています。
私がやっていること:
src/flavor1/google-services.json
とsrc/flavor2/google-services.json
という2つのフレーバーがあり、それぞれに対応する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
}
制限事項: 異なるフレーバーを実行したい場合は毎回gradleでmyFlavor
manualを変更する必要があります(ハードコードされているため)。
私はafterEvaluate
closeのような現在のビルドフレーバーを得るために多くの方法を試してみました...これまでより良い解決策を得ることができませんでした。
更新、別の解決策:すべてのフレーバーに対して1つのgoogle-services.json:
フレーバーごとに異なるパッケージ名を付けてから、 Googleデベロッパーコンソールで 各フレーバーごとに2つの異なるアプリケーションを作成する必要はなく、同じアプリケーション内に2つの異なるクライアントを作成する必要はありません。そうすると、両方のクライアントを含むgoogle-services.json
が1つだけになります。もちろん、これはあなたがあなたのフレーバーのバックエンドをどのように実装しているかに依存します。それらが分離されていない場合、この解決策はあなたを助けません。
ここから作成したgoogle-services.jsonファイルを使用しています。 https://developers.google.com/mobile/add?platform=Android&cntapi=gcm&cnturl=https:%2F%2Fdevelopers.google.com% 2Fクラウド・メッセージング%2Fandroid%2Fclient&cntlbl =続行%20追加%20GCM%20サポート&%3F構成%3Dtrue
JSON構造には、clientsという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"
}
私のプロジェクトでは同じproject-idを使用していて、上記のURLに2番目のpackage-nameを追加すると、googleからjson-dataに複数のクライアントを含むファイルが提供されます。
コンパクトなJSONデータでごめんね。正しくフォーマットできませんでした...
google-services.jsonファイルは通知を受け取るのに不要です。 build.gradleファイルに各フレーバーの変数を追加するだけです。
buildConfigField "String", "GCM_SENDER_ID", "\"111111111111\""
登録時に、getString(R.string.gcm_defaultSenderId)の代わりにこの変数BuildConfig.GCM_SENDER_IDを使用します。
instanceID.getToken(BuildConfig.GCM_SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
1.)google-services.jsonは実際に何をしますか?
これに従ってください: https://stackoverflow.com/a/31598587/2382964
2.)google-services.jsonファイルはAndroid studioプロジェクトにどのように影響しますか?
これに従ってください: https://stackoverflow.com/a/33083898/2382964
要するに2番目のURLです。プロジェクトにgoogle-services.jsonを追加する場合、このパスにdebug
バリアントの自動生成google-services
フォルダーが必要です。
app/build/generated/res/google-services/debug/values/values.xml
3.)何をすべきか、それを成し遂げるために?
project_level
build.gradleにgoogle-services依存関係を追加します。app_compactライブラリを使用している場合は、version 3.0.0
も使用できます。
// 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があり、app/google-service.json
内に単一のgoogle_services.jsonファイルがある場合。
私たちはデバッグビルドのための別のパッケージ名(* .debug)を持っているので、processDebugFlavorGoogleServices
のパターンでフレーバー関連のものを書く必要なしに、フレーバーとbuildTypeに基づいて動作する何かが欲しかった。
デバッグ版とリリース版の両方のjsonファイルを含む "google-services"という名前のフォルダを各フレーバーで作成しました。
GradleファイルのbuildTypesセクションに、以下を追加してください。
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ファイルが自動的にコピーされます。
現在のフレーバーと現在のビルドタイプを取得するために呼び出される2つのメソッドを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ファイルからフレーバーを削除/追加/変更することを心配する必要はありません、そしてそれは自動的にdebugまたはrelease google-services.jsonを得ます。
Firebaseは1つのgoogle-services.jsonファイルで複数のアプリケーションIDをサポートするようになりました。
このブログ記事 で詳しく説明しています。
Firebaseで1つの親プロジェクトを作成し、それをすべてのバリアントに使用します。次に、そのプロジェクトの下にあるFirebase内のアプリケーションIDごとに、別々のAndroidアプリケーションを作成します。
すべてのバリアントを作成したら、すべてのアプリケーションIDをサポートするgoogle-services.jsonをダウンロードできます。データを個別に表示することが重要な場合(クラッシュレポートなど)、ドロップダウンを使用してそれを切り替えることができます。
更新しました:
ビルドバリアントを使用したFirebaseのセットアップに関しては、 このブログ を参照してください。
@ 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
というファイルが必要です。使用しているもののフレーバー名を置き換えます。
追加のグラドルスクリプトは必要ありません。
Googleは「Android_client_info」という名前で別のパッケージ名を追加し始めました。 google-services.jsonでは以下のようになります。
"Android_client_info": {
"package_name": "com.Android.app.companion.dev"
}
そのため、次の手順で別のgoogle-services.jsonを選択できます。
それだ!..
google-services プラグインはGCMを追加したいプロジェクトにはまったく役に立たないことがわかりました。単にプロジェクトIDを文字列リソースとして追加する次のファイルを生成するだけです。
<?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プロジェクトを切り替えることができるようにしたい場合は、独自の定数を定義して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);
製品フレーバーの場合
上記のコードはデバッグビルドとリリースビルドを切り替えるために機能します。製品フレーバーの場合は、Javaソースファイルに異なるAPIキーを定義し、それらのファイルを対応する製品フレーバーディレクトリに配置します。参考のために: Gradle Build Variants
Googleサービスプラグインのポイントは、Google機能の統合を簡素化することです。
それはgoogle-services.jsonファイルからAndroidリソースを生成するだけなので、過度に複雑なgradle-logicはこの点を否定します、と私は思います。
そのため、GoogleドキュメントでGoogleの特定の機能に必要なリソースがわからない場合は、関連するビルドタイプ/フレーバーごとにJSONファイルを生成し、プラグインによって生成されるリソースを確認して、それらのリソースを手動で配置するそれぞれのsrc/buildtypeORflavor/resディレクトリに。
その後google-servicesプラグインとJSONファイルへの参照を削除すれば完了です。
Google-services gradle-pluginの内部動作の詳細については、私の他の答えを参照してください。
@Scottiが言ったことを単純化します。製品の種類に応じて、特定のプロジェクトに対して異なるパッケージ名でMultiplesアプリを作成する必要があります。
あなたのプロジェクトが異なる製品フレーバーX、Yを持つABCで、Xがパッケージ名com.xを持ち、Yがパッケージ名com.yを持つと仮定します。そしてfirebaseコンソールであなたは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"
}
]
}
ちょっと仲間たちはまた小文字だけの名前の使用を探します。
確かに、MyApp/app/
ディレクトリに1つのgoogle-services.jsonを置くことは良いことです、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
を削除するように注意してください。
あなたは多くの風味を持っているので、それはあなたが多くの違いパッケージIDを持つことになるということですね。それで、ちょうどあなたがあなたのjsonファイルと各パッケージ名のためのあなたのjsonファイルとconfigを設定/生成するページに行きなさい。それはすべてJSONファイルに追加されます。
私は今すぐ写真を投稿するのが面倒ですが、基本的には:
ファイルを設定すると、そのGoogleがサーバーAPIキー+送信者IDを表示していることがわかります。そしてそれはすべてのパッケージ(味)のために同じです
最後に、すべてのフレーバーに必要なJSONファイルは1つだけです。
登録トークンを取得するには、登録時にテストする必要があるという、ここでもう1つ質問があります。各フレーバーの違いを確認してください。触れませんが、違いがあるはずです。今は遅すぎるし、私はとても眠い:)それが助けを願っています!
したがって、プログラムですべてのバリアントから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
ファイルを用意する必要があります。ここに例を示します。
私は現在、同じアプリパッケージ内で2つのGCMプロジェクトIDを使用しています。最初のGCMプロジェクトのgoogle-service.jsonを入れましたが、SENDER_IDを変更するだけで、最初のプロジェクトから2番目のプロジェクトに切り替えます。
String token = instanceID.getToken(SENDER_ID,GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
(現時点では、google-services.jsonは必須ではないと思います)
あなたの "google-services.json"ファイルをそれぞれapp/src/flavorsの下に置き、次にappの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'
}
}
}
}
}
上記の@ ahmed_khan_89の回答に触発されました。このようにして直接ファイルに保存できます。
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
}