I am using the Firebase App Distribution with the Gradle plugin.
When I try to run the appDistributionUploadDebug command I receive the error:
Getting appId from output of google services plugin
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:appDistributionUploadDebug'.
> Missing app id
I included the plugin in the build.gradle file
dependencies {
classpath 'com.google.firebase:firebase-appdistribution-gradle:1.2.0'
}
Then I added the config:
apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.appdistribution'
android {
//...
debug {
firebaseAppDistribution {
serviceAccountCredentials = "/path/to/your-service-account-key.json"
releaseNotesFile="/path/to/releasenotes.txt"
testers="email#example.com"
}
}
}
If you are not using the google services gradle plugin in your project you have to add the appId property in your configuration.
Something like:
firebaseAppDistribution {
// Firebase App Distribution setup
appId = "...." //<-- add your appID
serviceAccountCredentials = "/path/to/your-service-account-key.json"
releaseNotesFile="/path/to/releasenotes.txt"
testers="email#example.com"
}
You can find the appId value in the google-services.json file
{
...
"client": [
{
"client_info": {
"mobilesdk_app_id": "...",//<-- YOU NEED THIS APP_ID
"android_client_info": {
"package_name": "..."
}
},
...
}
or in the Firebase console on the Project Settings page -> General Tab.
Distribute Android apps to testers using Gradle
Output error on appDistributionVersion 2.0.0:
Could not find the APK. Make sure you build first by running ./gradlew
assemble[Variant]
So that the APK can be found, make sure you build first by running ./gradlew assemble[Variant] and then ./gradlew appDistributionUpload[Variant].
$ ./gradlew assemble[Variant] appDistributionUpload[Variant]
Related
While adding a project as a module
What went wrong:
It is too late to modify excludes
It has already been read to configure the project.
Consider either moving this call to be during evaluation, are using the variant API.
Steps followed: File -> Import module -> selec project file
Gradle Failed Exception
My project uses gRPC and this exception occurred.
Updating the version of Protobuf Plugin for Gradle from 0.8.13 to 0.9.1 resolved the error.
buildscript {
ext.versions = [
protobuf : [
plugin: "0.9.1",
],
]
dependencies {
classpath "com.google.protobuf:protobuf-gradle-plugin:$versions.protobuf.plugin"
}
}
I have a multi-flavored, multi-build-typed android project and I want to integrate the NewRelic plugin. But I have to apply it only for one of the customers, thus only for one product flavor.
NewRelic uses instrumentation and the plugin would generate code in other flavors if I applied the plugin there, and that is not permitted for us.
So my question is: How can I use the apply plugin: something command in the gradle file to be applied to only one of my flavors?
Use this code:
if (!getGradle().getStartParameter().getTaskRequests()
.toString().contains("Develop")){
apply plugin: 'com.google.gms.google-services'
}
getGradle().getStartParameter().getTaskRequests().toString() returns something like [DefaultTaskExecutionRequest{args=[:app:generateDevelopDebugSources],projectPath='null'}] so as stated in the comments Develop must start with an uppercase.
Tried different solutions, but none of them worked for me. This is what I came up with and seems to work as far as I tested:
build.gradle
productFlavors {
someFlavorWithGoogleGcm {
dimension "type"
applicationId "com.example.withGcm"
ext.useGoogleGcm = true
}
someFlavorWithoutGoogleGcm {
dimension "type"
applicationId "com.example.withoutGcm"
}
}
And outside the configuration, inside the build.gradle file:
android.productFlavors.each { flavor ->
if (getGradle().getStartParameter().getTaskRequests().toString().toLowerCase().contains(flavor.name) && flavor.ext.useGoogleGcm) {
println("Building flavor with Google GCM [${flavor.name}] - applying plugin")
apply plugin: 'com.google.gms.google-services'
}
}
I simply used apply plugin: 'com.google.gms.google-services' inside the flavor in app level build.gradle and it works just fine.
productFlavors {
..... your other flavors ....
yourFlv {
....
....
apply plugin: 'com.google.gms.google-services'
}
}
No extra step needed.
Define variable - def fl
Initialize variable in you Flavours (and/or builds)
productFlavors {
freeFlavour {
(...)
fl = "free"
}
paidFlavour {
(...)
fl = "paid"
}
}
Use if statement -
if (fl == "free") {
apply plugin: something
}
I found a solution, but it is not the best so far.
So I'm not sure anymore, that what I wanted to do initially is possible.
The gradle file evaluation and the choosing of the right flavor and build type is in different phases of the gradle build, so what I've done is:
I use a build parameter from the command line. When that paramerer is true, I apply the plugin, when it is not even there, I also apply it (for IDE build).
I use Jenkins, so I could write that parameter in the build job.
build.gradle file:
// First we have to attach a task to the project, which will be running first
gradle.projectsEvaluated {
preBuild.dependsOn(applyNewRelicByProperty)
}
// Then check on the parameter, which comes from the command line
task applyNewRelicByProperty {
if(!project.hasProperty('compileNewRelic')) {
// NewRelic on: 'compileNewRelic' property not set, so running from IDE.
apply plugin: 'newrelic'
} else if(project.hasProperty('compileNewRelic') && project.getProperties().get('compileNewRelic').equals('true')) {
// NewRelic on: 'compileNewRelic' property is set and it is 'true'.
apply plugin: 'newrelic'
} else {
// NewRelic off
println("No NewRelic")
}
}
And you have to run the gradle build by this:
assembleYourApp -PcompileNewRelic=true
After upgrading to Gradle 4.2, the approach by Tarps stopped working, so I ended up combining it with Erik's answer.
Set ext.useGoogleGcm for each flavour in your build.gradle:
productFlavors {
a {
...
ext.useGoogleGcm = true
}
b {
...
ext.useGoogleGcm = false
}
}
Then at the bottom of the file:
apply plugin: 'com.google.gms.google-services'
afterEvaluate {
android.productFlavors.each { flavor ->
tasks.matching {
it.name.contains('GoogleServices') && it.name.contains(flavor.name.capitalize())
}*.enabled = flavor.ext.useGoogleGcm
}
}
In the output for your assembleRelease task, you should see tasks with "GoogleServices" in the name have run for those that are true and skipped for those that are false. If your build complains about toCapitalize, you could use toLowerCase on both it.name and flavor.name.
In the case of the Google Services Gradle plugin, the following works.
apply plugin: 'com.google.gms.google-services'
afterEvaluate {
tasks.matching { it.name.contains("GoogleServices") && !it.name.contains(yourFlavorName) }*.enabled = false
}
where yourFlavorName is a capitalised string containing the name of your flavor that must apply the plugin; all other flavors don't use the plugin.
Note that the plugin is still applied to other flavors; this solution just disables the *GoogleServices* task(s) for them. That assumes that the Google Services Gradle plugin only applies changes by adding a task containing substring "GoogleServices", which might not work in the future.
To check that this works, you can check the dependencies, e.g. like so:
./gradlew app:dependencyInsight --configuration yourFlavorNameDebugCompileClasspath --dependency google | grep -i services
That should show some dependencies for yourFlavorName but not for other flavor names:
./gradlew app:dependencyInsight --configuration otherFlavorNameDebugCompileClasspath --dependency google | grep -i services
I have an Android library project and I am trying to publish the AAR files to JFrog artifactory using gradle.
Once I have the AAR files and when I execute the build task, the publish is working as expected, the problem is that I am not able to do it as part of my build process if the AAR files are not there.
I want to publish the AAR files when ever a new one is available. I tried to put assembleIntegrated.finalizedBy (artifactoryPublish), but that didn’t help.
The publish task gets triggered before the AARs are generated.
mygradle.gradle -->
apply plugin: 'com.jfrog.artifactory'
apply plugin: 'maven-publish'
File AARFile1 = file("$buildDir/outputs/aar/my_aar_file1.aar")
File AARFile2 = file("$buildDir/outputs/aar/my_aar_file2.aar")
publishing {
publications {
AAR1(MavenPublication) {
groupId repoFolder
version libVersion
// Tell maven to prepare the generated "*.aar" file for publishing
if (AARFile1.exists()) {
artifactId libRelease
artifact(AARFile1)
} else {
println 'AAR1 files not found in' + AARFile1.absolutePath
}
}
AAR2(MavenPublication) {
groupId repoFolder
version libVersion
// Tell maven to prepare the generated "*.aar" file for publishing
if (AARFile2.exists()) {
artifactId libDebug
artifact(AARFile2)
} else {
println 'AAR2 files not found in' + AARFile2.absolutePath
}
}
}
}
artifactory {
contextUrl = "https://bintray.com/jfrog/artifactory:8080"
publish {
repository {
// The Artifactory repository key to publish to
repoKey = 'my_key'
username = 'my_username'
password = 'my_encrypt_password'
}
defaults {
// Tell the Artifactory Plugin which artifacts should be published to Artifactory.
if (AARFile1.exists() || AARFile2.exists()) {
publications('AAR1', 'AAR2')
publishArtifacts = true
// Properties to be attached to the published artifacts.
properties = ['qa.level': 'basic', 'dev.team':'Me' ]
// Publish generated POM files to Artifactory (true by default)
publishPom = true
}
}
}
}
I see the gradle tasks list as below:
executing tasks: [assembleIntegrated]
AAR1 files not found in /myfolder/.../my_lib_project/app/build/outputs/aar/my_aar_file1.aar
AAR2 files not found in /myfolder/.../my_lib_project/app/build/outputs/aar/my_aar_file2.aar
.
.
.
> Task :app:preBuild UP-TO-DATE
> Task :app:test UP-TO-DATE
> Task :app:check
> Task :app:build
> Task :app:artifactoryPublish
> Task :artifactoryDeploy
It happens, because you add files manually to the maven publication. When maven publish runs, these files are not exists. So, you should configure task dependencies manually. When you add a publication to your project, Gradle will generate some tasks with combination of your publication names, and repo names. Something like that: publish{publicationName}PublicationTo{RepositoryName}Repository. Thus, you should setup these task to depends on assembleIntegration task.
Or you can use android-maven-publish plugin, which do this work automatically.
I am trying to upload my APK to Nexus repository.
Below code work fine until I have change gradle version
from
classpath 'com.android.tools.build:gradle:2.3.3'
distributionUrl=https://services.gradle.org/distributions/gradle-3.3-all.zip
mCompileSdkVersion=23 mBuildToolsVersion='25.0.0'
To
classpath 'com.android.tools.build:gradle:3.1.0'
distributionUrl=https://services.gradle.org/distributions/gradle-4.4-all.zip
mCompileSdkVersion=27 mBuildToolsVersion='27.0.0'
After changing versions same code is not work I am not able to understand where I found an error, Terminal not showing any error message but my APK is not uploaded in given location
following is the current configuration of my App build.gradle file
apply plugin: 'com.android.application'
apply plugin: 'maven'
task uploadRelease (type: Upload){
configuration = project.getConfigurations().getByName('archives');
repositories {
mavenDeployer {
repository( url: "http://XXXXXXXX:8081/nexus/XXXXXXXX/repositories/releases" ) {
authentication(userName: "MyuserName", password: "Mypassword")
}
pom.project {
version "${android.defaultConfig.versionName}"
artifactId "Collection"
name "xxxxxxxx"
groupId "com.xxxxxxxx.mobile.xxxxxxxx.collections"
}
}
}
}
task uploadSnapshot (type: Upload){
configuration = project.getConfigurations().getByName('archives');
repositories {
mavenDeployer {
repository( url: "http://XXXXXXXX:8081/nexus/XXXXXXXX/repositories/snapshots" ) {
authentication(userName: "MyuserName", password: "Mypassword")
}
pom.project {
version "${android.defaultConfig.versionName}-SNAPSHOT"
artifactId "Collection"
name "Collection"
groupId "com.xxxxxxxx.mobile.xxxxxxxx.collections"
}
}
}
}
I use Command as - gradle assemblerelease uploadsnapshot
to build and upload APK but It does not work for gradle 4.4 Please let me know what went wrong
The new Android Gradle Plugin version 3.+ relocate the apk to a different paths compared to 2.2.3.
Some errors may happen at below line
configuration = project.getConfigurations().getByName('archives');
Use gradle assemblerelease uploadsnapshot --debug --info --stacktrace to gather more information and analyse the error logs.
The older apk location is
build/outputs/apk/*.apk
the apk location for AGP 3.x is
build/outputs/apk/<flavour>/<buildtype>/<name>-<buildtype>.apk
so
def apk = file('build/outputs/apk/release/iMobility-release.apk')
artifacts {
archives apk
}
This is to overwrite the paths of archives with the correct apk location.
Not the actual answer but what work for me is
Put this line below your
task uploadSnapshot (type: Upload){
configuration = project.getConfigurations().getByName('archives');
repositories {
mavenDeployer {
repository( url: "http://XXXXXXXX:8081/nexus/XXXXXXXX/repositories/snapshots" ) {
authentication(userName: "MyuserName", password: "Mypassword")
}
pom.project {
version "${android.defaultConfig.versionName}-SNAPSHOT"
artifactId "Collection"
name "Collection"
groupId "com.xxxxxxxx.mobile.xxxxxxxx.collections"
}
}
}
}
def apk = file('build/outputs/apk/release/iMobility-release.apk')
artifacts {
archives apk
}
Can any one explain this why ? and have a better option then this ?
Is there any way to run gradle task from app/build.gradle file, so that when I build release APK task "firebaseUploadReleaseProguardMapping" will run automatically.
You can use dependsOn for example (your app/build.gradle):
apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.firebase-crash'
android {
}
dependencies {
}
task release
task archiveRelease(type: Copy) {
from './build/outputs/apk', './build/outputs/'
into "../releases/${rootProject.ext.configuration.version_code}"
include('app-release.apk', 'mapping/release/mapping.txt')
rename('app-release.apk', "${rootProject.ext.configuration.package}_${rootProject.ext.configuration.version_name}_${rootProject.ext.configuration.version_code}.apk")
}
project.afterEvaluate {
dependencyUpdates.dependsOn clean
assembleRelease.dependsOn clean
def publishApkRelease = project.tasks.getByName("publishApkRelease")
publishApkRelease.dependsOn assembleRelease
release.dependsOn publishApkRelease, firebaseUploadReleaseProguardMapping, archiveRelease
}
I created a new task called release. It depends on publishApkRelease (comes from gradle-play-publisher), firebaseUploadReleaseProguardMapping and archiveRelease. And publishApkRelease depends on assembleRelease.
At the ned you just call ./gradlew release and it will build your release version, uploads the apk to Google play, the mapping file to Firebase and archive a copy of the apk and mapping file.