我按照Google Developers页面here
的指南实施新的Google云消息传递我已成功运行并测试它。但我现在的问题是我有不同的产品风格,不同的applicationId / packageName和不同的Google Cloud Messaging Project Id。 google-services.json
必须放在/app/google-services.json
而不是flavors文件夹中。
有没有办法让google-services.json
配置与许多版本不同?
答案 0 :(得分:452)
Google在播放服务插件的2.0版本中包含了对flavor的支持。从此版本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,这对我也有用。我有免费的&在一个维度支付和Mock&在另一个方面产生刺激。我还有3个buildTypes:debug,release和staging。这就是我在FreeProd风格项目中的表现:
google-services.json文件的数量取决于您项目的特征,但每个Google项目至少需要一个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 :(得分:54)
更新:以下说明适用于一个Android Studio项目,该项目中包含一个Firebase项目和不同的Firebase应用程序。 如果目标是在同一个Android Studio项目中为不同的Firebase项目中的不同Firebase应用程序提供不同的JSON文件,(或者如果您不知道区别的是什么)look here.。
每个Android应用程序ID(通常是程序包名称)需要一个Firebase应用程序。每个Gradle构建变体有一个应用程序ID是常见的(如果您使用Gradle构建类型和Gradle构建样式,这将是可能的)
从 Google Services 3.0 开始,使用 Firebase ,不必为不同的风格创建不同的文件。如果你有相互组合的productFlavours和Build类型,那么为不同的风格创建不同的文件可能不明确或不直接。
在同一个文件中,您将拥有所有构建类型和风格所需的所有配置。
在Firebase控制台中,您需要为每个程序包名称添加一个应用程序。想象一下,你有2种风格(开发和实时)和2种构建类型(调试和发布)。根据您的配置,您可能有4个不同的包名称,如:
您需要在Firebase控制台中使用4种不同的Android应用。 (在每一个上,您需要为您正在使用的每台计算机添加SHA-1进行调试和实时)
当您下载google-services.json文件时,实际上它与您下载的应用程序无关,它们都包含与您所有应用相关的相同信息。
现在您需要在应用级别找到此文件(app /)。
如果您打开该文件,您会看到如果包含所有包名称的所有信息。
痛点用作插件。为了使其正常工作,您需要在文件底部找到插件。所以这一行..
apply plugin: 'com.google.gms.google-services'
...需要位于app build.gradle文件的底部。
对于这里所说的大部分内容,它也适用于以前的版本。我从来没有为不同的配置提供不同的文件,但现在使用Firebase控制台更容易,因为它们为您提供了所有配置所需的一切文件。
答案 2 :(得分:38)
在这个问题上写了Medium post。
有一个类似的问题(使用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
任务在每个风味级别修改它。
答案 3 :(得分:12)
好吧,我遇到了同样的问题,无法得到任何完美的解决方案。这只是一种解决方法。 我想知道谷歌如何不考虑口味......?我希望他们能尽快提出更好的解决方案。
我在做什么:
我有两种口味,每一种我都放了相应的google-services.json:src/flavor1/google-services.json
和src/flavor2/google-services.json
。
然后在构建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
(因为它是硬编码的)。
我尝试了许多方法来获取当前构建的风格,例如afterEvaluate
关闭......直到现在才能得到更好的解决方案。
更新,另一个解决方案:一个google-services.json用于所有风格:
您还可以为每种风格设置不同的包名称,然后在google developer console中,您不必为每种风格创建两个不同的应用程序,而只需在同一个应用程序中创建两个不同的客户端。
然后,您将只有一个google-services.json
包含您的两个客户端。
当然,这取决于你如何实现你的口味的后端。如果他们没有分开,那么这个解决方案对你没有帮助。
答案 4 :(得分:12)
根据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 '.'
}
}
}
然后您不必手动切换设置。
答案 5 :(得分:8)
我正在使用从此处创建的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结构中有一个名为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中添加第二个package-name时,google为我提供了一个包含json-data中多个客户端的文件。
对于紧凑的JSON数据感到抱歉。我无法正确格式化...
答案 6 :(得分:8)
google-services.json文件无需接收通知。只需为build.gradle文件中的每个flavor添加一个变量:
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 :(得分:5)
1。) google-services.json真正做了什么?
请遵循:https://stackoverflow.com/a/31598587/2382964
2。) google-services.json文件如何影响您的Android工作室项目?
请遵循:https://stackoverflow.com/a/33083898/2382964
就第二个网址而言,如果您在项目中添加google-services.json,则此路径中的google-services
变体必须有一个自动生成的debug
文件夹
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并且您在app/src/build_flavor/google-service.json
内放置了不同的google_services.json文件。
案例3.)如果您有多个build_flavor并且您将单个google_services.json文件放在app/google-service.json
内。
答案 8 :(得分:4)
Firebase现在支持使用一个google-services.json文件的多个应用程序ID。
This blog post详细描述了它。
您将在Firebase中创建一个您将用于所有变体的父项目。然后,您可以在该项目的Firebase中为您拥有的每个应用程序ID创建单独的Android应用程序。
创建所有变体后,您可以下载支持所有应用程序ID的google-services.json。如果单独查看数据(即崩溃报告)是相关的,您可以使用下拉列表切换。
答案 9 :(得分:4)
我们为调试版本(* .debug)提供了不同的软件包名称,所以我想要一些基于flavor和buildType的东西,而不必在processDebugFlavorGoogleServices
的模式中编写与风格相关的内容。
我在每种风格中创建了一个名为“google-services”的文件夹,其中包含调试版本和json文件的发行版本:
在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文件。
添加两个调用的方法,以获取build.gradle根目录下的当前flavor和当前构建类型
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文件中删除/添加/修改flavor,它会自动获得调试或发布google-services.json。
答案 10 :(得分:3)
更新:
有关构建版本的Firebase设置,请参阅this blog,其中包含详细说明。
答案 11 :(得分:3)
根据Firebase docs,您还可以使用字符串资源代替 google-services.json 。
因为此提供程序仅在读取具有已知名称的资源,所以另一种选择是将字符串资源直接添加到您的应用程序中,而不是使用Google Services gradle插件。您可以通过以下方式做到这一点:
- 从您的root build.gradle移除
zgrep
插件- 从项目中删除
google-services
- 直接添加字符串资源
- 从应用程序build.gradle中删除应用插件:
google-services.json
示例'com.google.gms.google-services'
:
strings.xml
答案 12 :(得分:3)
无需任何额外的gradle脚本。
Google开始在' android_client_info'的名称中添加不同的软件包名称。它在google-services.json下面如下所示
"android_client_info": {
"package_name": "com.android.app.companion.dev"
}
因此,以下步骤足以让不同的google-services.json选择。
就是这样!..
答案 13 :(得分: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
答案 14 :(得分:3)
根据@ 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
个文件。替换您使用的名称的风味名称。
答案 15 :(得分:2)
google-services插件的目的是简化Google功能的集成。
由于它只从google-services.json文件中生成android-resources,因此我认为过于复杂的gradle-logic否定了这一点。
因此,如果Google-docs没有说明特定Google功能需要哪些资源,我建议为每个相关的构建类型/风格生成JSON文件,查看插件生成的资源然后放入这些资源手动进入各自的src / buildtypeORflavor / res目录。
之后删除对google-services插件和JSON文件的引用,您就完成了。
有关google-services gradle-plugin内部工作原理的详细信息,请参阅我的其他答案:
答案 16 :(得分:2)
简化@Scotti的说法。您需要根据产品风格为特定项目创建具有不同包名称的Multiples应用程序。
假设您的项目是ABC,具有不同的产品风格X,Y,其中X的包名称为com.x,Y的包名称为com.y,然后在firebase控制台中,您需要创建一个项目ABC,您需要在其中使用软件包名称com.x和com.y创建2个应用程序。然后你需要下载google-services.json文件,其中将有2个包含那些pacakges的客户信息对象,你将会很高兴。
json的片段就是这样的
{
"client": [
{
"client_info": {
"android_client_info": {
"package_name": "com.x"
}
{
"client_info": {
"android_client_info": {
"package_name": "com.y"
}
]
}
答案 17 :(得分:2)
因此,如果您要以编程方式将google-services.json
文件从所有变体中复制到根文件夹中。当您切换到特定版本时,这是您的解决方案
android {
applicationVariants.all { variant ->
copy {
println "Switches to $variant google-services.json"
from "src/$variant"
include "google-services.json"
into "."
}
}
}
此方法有一个警告,那就是您需要在每个Variants文件夹中都有google-service.json
文件,这是一个示例。
答案 18 :(得分:1)
嘿嘿朋友们也只使用小写来查找姓名然后你不会收到此错误
答案 19 :(得分:1)
你有很多味道,所以这意味着你会有很多不同的包ID,对吧?因此,只需转到设置/生成json文件的页面并为每个包名配置。所有这些都将添加到json文件中。
我现在懒得发布图片,但基本上是:
配置文件时,您可以看到谷歌显示服务器API密钥+发件人ID。所有包装(口味)都是一样的
最后,您只需要一个json文件用于所有风格。
此处还有一个问题是,当您注册获取注册令牌时,您必须进行测试,检查每种口味是否有差异。我不接触它,但它认为它应该是不同的。现在太晚了,我好困啊:)希望它有所帮助!
答案 20 :(得分:1)
确实,MyApp/app/
目录中的一个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
答案 21 :(得分:1)
简短答案:
google-services.json
复制到 app 目录。对于其他风味,请将google-services.json
复制到 app / src / {flavor-name} 目录
答案 22 :(得分:1)
google-services.json
。google-services.json
.. mine放在哪里的样子。
File google-services.json is missing. The Google Services Plugin cannot function without it.
Searched Location:
C:\Users\username\Desktop\HelloWorld\app\src\devSuffixYes_EnvQaApistaging_\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\devSuffixYes_EnvQaApistaging_Debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\devDebug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\devSuffixYes_EnvQaApistaging_\debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\debug\devSuffixYes_EnvQaApistaging_\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffixDebug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_Debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\env\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\envDebug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\env\debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\env\qa\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\env\qaDebug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\env\qa\debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\env\qa\apistaging_\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\env\qa\apistaging_Debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\src\dev\suffix\yes_\env\qa\apistaging_\debug\google-services.json
C:\Users\username\Desktop\HelloWorld\app\google-services.json
注意:它也关心flavorDimensions
中声明的顺序。我的是flavorDimensions "dev_suffix", "environment"
答案 23 :(得分:0)
灵感来自@ 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
}
答案 24 :(得分:0)
放置您的&#34; google-services.json&#34;分别在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'
}
}
}
}
}
答案 25 :(得分:0)
我目前在同一个应用包中使用两个GCM Project Id。我把我的第一个GCM项目的google-service.json,但是我从第一个切换到第二个只改变了SENDER_ID:
String token = instanceID.getToken(SENDER_ID,GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
(此时我认为google-services.json不是强制性的)
答案 26 :(得分:0)
+
答案 27 :(得分:0)