web-dev-qa-db-ja.com

さまざまな製品のためのgoogle-services.jsonフレーバー

更新: _ gcm _ は非推奨です。 _ fcm _ を使用してください。

Google Developersページのガイドに従って、新しいGoogle Cloud Messagingを実装しています ここ

実行してテストしました。しかし、今私の問題は、異なるapplicationId/packageNameと異なるGoogle Cloud MessagingプロジェクトIDを持つ異なる製品フレーバーがあることです。 google-services.jsonはフレーバーフォルダーではなく/app/google-services.jsonに配置する必要があります。

多くのフレーバーでgoogle-services.json設定を異なるものにする方法はありますか?

400
gentra

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フレーバーの見方です。

enter image description here

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

451
Yair Kukielka

更新: 以下の説明は、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つの異なるパッケージ名がある可能性があります。

  • com.stackoverflow.example(ライブ - リリース)
  • com.stackoverflow.example.dev(live - dev)
  • com.stackoverflow.example.debug(デバッグ - リリース)
  • com.stackoverflow.example.dev.debug(debug - dev)

Firebase Consoleには4つの異なるAndroidアプリが必要です。 (それぞれに、デバッグ用にSHA-1を追加し、使用している各コンピュータに対応する必要があります)

Google-services.jsonファイルをダウンロードしても、実際にはどのアプリをダウンロードしても問題ありません。すべてのアプリに同じ情報が含まれています。

今、あなたはアプリレベル(app /)でこのファイルを見つける必要があります。

enter image description here

そのファイルを開くと、すべてのパッケージ名に関するすべての情報が含まれていることがわかります。

問題点は、プラグインになることです。それを機能させるためには、あなたのファイルの一番下にプラグインを配置する必要があります。だからこの行..

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

...あなたのアプリのbuild.gradleファイルの一番下にある必要があります。

ここで述べたことのほとんどについては、それは以前のバージョンにも適用されます。設定ごとに異なるファイルを作成したことは一度もありませんが、Firebase consoleでは、すべての設定に必要なものがすべて1つのファイルにまとめられているので、簡単になりました。

54
Sotti

この問題について 中程度の投稿 を書きました。

(Flavorsの代わりにBuildTypesを使用して)同様の問題を抱えていて、そのように修正しました。

Gradleの依存管理システムを利用してください。 switchToDebugswitchToReleaseの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タスクを使用して、フレーバーごとのレベルで変更します。

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

まあ私は同じ問題に遭遇していて、どんな完璧な解決策も得られませんでした。これは単なる回避策です。グーグルがどのようにフレーバーについて考えなかったのかと思っています…?そして私は彼らがすぐにもっと良い解決策を提案することを願っています。

私がやっていること:

src/flavor1/google-services.jsonsrc/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でmyFlavormanualを変更する必要があります(ハードコードされているため)。

私はafterEvaluate closeのような現在のビルドフレーバーを得るために多くの方法を試してみました...これまでより良い解決策を得ることができませんでした。

更新、別の解決策:すべてのフレーバーに対して1つのgoogle-services.json:

フレーバーごとに異なるパッケージ名を付けてから、 Googleデベロッパーコンソールで 各フレーバーごとに2つの異なるアプリケーションを作成する必要はなく、同じアプリケーション内に2つの異なるクライアントを作成する必要はありません。そうすると、両方のクライアントを含むgoogle-services.jsonが1つだけになります。もちろん、これはあなたがあなたのフレーバーのバックエンドをどのように実装しているかに依存します。それらが分離されていない場合、この解決策はあなたを助けません。

12
ahmed_khan_89

ここから作成した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データでごめんね。正しくフォーマットできませんでした...

8
Mark Martinsson

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);
8
divonas

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ファイルがある場合。

5
Tushar Pandey

私たちはデバッグビルドのための別のパッケージ名(* .debug)を持っているので、processDebugFlavorGoogleServicesのパターンでフレーバー関連のものを書く必要なしに、フレーバーとbuildTypeに基づいて動作する何かが欲しかった。

デバッグ版とリリース版の両方のjsonファイルを含む "google-services"という名前のフォルダを各フレーバーで作成しました。

enter image description here

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を得ます。

4
FallasB

Firebaseは1つのgoogle-services.jsonファイルで複数のアプリケーションIDをサポートするようになりました。

このブログ記事 で詳しく説明しています。

Firebaseで1つの親プロジェクトを作成し、それをすべてのバリアントに使用します。次に、そのプロジェクトの下にあるFirebase内のアプリケーションIDごとに、別々のAndroidアプリケーションを作成します。

すべてのバリアントを作成したら、すべてのアプリケーションIDをサポートする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.jsonsrc/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. Google analystics設定ページに新しいdev flavourのパッケージを追加し、google-services.jsonをダウンロードしてください。
  3. 新しい設定ファイルで、あなたのフレーバーのパッケージIDの両方がそこにあることに注意してください。
  4. フレーバービルドを準備してください。

それだ!..

3

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

3
kjones

Googleサービスプラグインのポイントは、Google機能の統合を簡素化することです。

それはgoogle-services.jsonファイルからAndroidリソースを生成するだけなので、過度に複雑なgradle-logicはこの点を否定します、と私は思います。

そのため、GoogleドキュメントでGoogleの特定の機能に必要なリソースがわからない場合は、関連するビルドタイプ/フレーバーごとにJSONファイルを生成し、プラグインによって生成されるリソースを確認して、それらのリソースを手動で配置するそれぞれのsrc/buildtypeORflavor/resディレクトリに。

その後google-servicesプラグインとJSONファイルへの参照を削除すれば完了です。

Google-services gradle-pluginの内部動作の詳細については、私の他の答えを参照してください。

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

2
arne.jans

@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"
        }
      ]

    }
2
Sagar Devanga

ちょっと仲間たちはまた小文字だけの名前の使用を探します。

1
Divyesh Jani

確かに、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を削除するように注意してください。

1
gigeos

あなたは多くの風味を持っているので、それはあなたが多くの違いパッケージIDを持つことになるということですね。それで、ちょうどあなたがあなたのjsonファイルと各パッケージ名のためのあなたのjsonファイルとconfigを設定/生成するページに行きなさい。それはすべてJSONファイルに追加されます。

私は今すぐ写真を投稿するのが面倒ですが、基本的には:

  • https://developers.google.com/mobile/add にアクセスします。
  • プラットフォームを選択
  • アプリを選択してください
  • _ important _ : "Android package name"フィールドにフレーバーパッケージ名を入力してください。
  • ...設定ファイルを入手してください。ダウンロードしてください。

ファイルを設定すると、そのGoogleがサーバーAPIキー+送信者IDを表示していることがわかります。そしてそれはすべてのパッケージ(味)のために同じです

最後に、すべてのフレーバーに必要なJSONファイルは1つだけです。

登録トークンを取得するには、登録時にテストする必要があるという、ここでもう1つ質問があります。各フレーバーの違いを確認してください。触れませんが、違いがあるはずです。今は遅すぎるし、私はとても眠い:)それが助けを願っています!

1
Lạng Hoàng

したがって、プログラムですべてのバリアントから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

0

私は現在、同じアプリパッケージ内で2つのGCMプロジェクトIDを使用しています。最初のGCMプロジェクトのgoogle-service.jsonを入れましたが、SENDER_IDを変更するだけで、最初のプロジェクトから2番目のプロジェクトに切り替えます。

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

(現時点では、google-services.jsonは必須ではないと思います)

0
ariostoi

あなたの "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'
                    }
                }
            }
        }
    }
0
Sameer Khader

上記の@ 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
}
0
Noundla Sandeep