26

I am creating a public android project and I am using Google Sign-In service. I am doing it according to this tutorial. As it says, I have got the google-services.json file.

  • Do I need to commit the above file to Github?
  • Do other developers (If someone contributes) need this file?
  • Or, do they have to create there own?
  • By the way I am using Travis-CI. Will this file affect to CI build?
Jayanga Kaushalya
  • 2,674
  • 5
  • 38
  • 58
  • 1
    It does look like a fairly essential file to me. – набиячлэвэли Dec 13 '15 at 20:05
  • 1
    Yes, But do I need to commit that file to Github? Since its containing my google app id and stuff doesn't that means that other developers should also generate it for themselves? – Jayanga Kaushalya Dec 16 '15 at 17:02
  • 5
    If it contains *your* sensitive data and is needed by Travis to build it, you can [file encrypt](https://docs.travis-ci.com/user/encrypting-files) it. If it doesn't contain sensitive data and is needed, add it. In all other cases ignore it. (I'd also look around if Android repos have it added and do the same) – набиячлэвэли Dec 16 '15 at 18:13
  • Google is [not recommending](https://firebase.google.com/docs/projects/learn-more?authuser=0#config-files-objects) including google-services.json in source control only for the open-source projects: "For open source projects, we generally do not recommend including the app's Firebase config file or object in source control because, in most cases, your users should create their own Firebase projects and point their apps to their own Firebase resources (via their own Firebase config file or object)." – Jacek Tymicki Jul 30 '21 at 10:00

4 Answers4

23

You can create a new build variant and store a template google-services.json to be used for your build on your CI platform in your app build.gradle.

Use a different google-services.json for the new dev build variant (see this post). Add the following google-services.json template to app/src/dev folder :

{
  "project_info": {
    "project_number": "",
    "project_id": ""
  },
  "client": [
    {
      "client_info": {
        "mobilesdk_app_id": "1:123456789012:android:1234567890123456",
        "android_client_info": {
          "package_name": "com.your.package"
        }
      },
      "oauth_client": [
        {
          "client_id": "",
          "client_type": 3
        },
        {
          "client_id": "",
          "client_type": 1,
          "android_info": {
            "package_name": "com.your.package",
            "certificate_hash": ""
          }
        }
      ],
      "api_key": [
        {
          "current_key": ""
        }
      ],
      "services": {
        "analytics_service": {
          "status": 2,
          "analytics_property": {
            "tracking_id": ""
          }
        },
        "appinvite_service": {
          "status": 1,
          "other_platform_oauth_client": []
        },
        "ads_service": {
          "status": 1
        }
      }
    }
  ],
  "configuration_version": "1"
}

Note that I have extended this google-services in case you also use Google Analytics or GCM service.

You would have the following configuration :

app/
├── src/
│   ├── main/
│   └── dev/
│       └── google-services.json
├── google-services.json
└── build.gradle

You can use either :

  • a new build type
  • a new product flavor (if you already have existing ones)

Build Type

Add the following build type:

buildTypes {

    dev {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

We don't need to build this "dev" build variant in regular build, so you can exclude this variant if a parameter is not specified. Add the following to your app build.gradle :

def build_param = "${build}";

if (build_param != "dev") {
    //exclude production build
    android.variantFilter { variant ->
        if (variant.buildType.name.equals('dev')) {
            variant.setIgnore(true);
        }
    }
} else {
    //exclude all except production build
    android.variantFilter { variant ->
        if (!variant.buildType.name.equals('dev')) {
            variant.setIgnore(true);
        }
    }
}

Product flavor

Add the dev product flavor to existing ones :

productFlavors {

    full {
    }

    dev {
    }
}

To remove this dev product flavor from the regular build :

def build_param = "${build}";

if (build_param != "dev") {
    //exclude dev
    android.variantFilter { variant ->
        if (variant.getFlavors().get(0).name.equals('dev')) {
            variant.setIgnore(true);
        }
    }
} else {
    //exclude all but dev
    android.variantFilter { variant ->
        if (!variant.getFlavors().get(0).name.equals('dev')) {
            variant.setIgnore(true);
        }
    }
}

Eventually, add your app module google-services.json to .gitignore :

app/google-services.json

We have previously ensured that this dev variant will only be used when parameter build=dev is specified

Edit .travis.yml to modify the build config :

script:
  - ./gradlew clean build -Pbuild=dev

-Pbuild=dev will only build dev build variant using google-services.json located in app/src/dev/google-services.json

Take a look at this sample project which is using google-services Google project

In Travis log, you can see that the JSON file being parsed is the one for the dev build variant :

Parsing json file: /home/travis/build/bertrandmartel/android-googlesignin/app/src/dev/google-services.json 

Extra Note

Note that this method is not limited to CI and can be extended for your production build when you require a production google-services.json or a different AndroidManifest.xml (with some specific properties like fabric.io key)

Check this method to prevent commitment of fabric keys embedded in AndroidManifest.xml (and can't be imported from gradle) that is using a different build variant and using a parameter to enable the production build.

Bertrand Martel
  • 42,756
  • 16
  • 135
  • 159
4

You can use travis encrypt-file google-services.json

Documentation

You can do it by:

  • installed the Travis CI Command Line Client by running $ gem install travis.

  • logged in to Travis CI using $ travis login or $ travis login --pro

    $ travis encrypt-file super_secret.txt
    encrypting super_secret.txt for rkh/travis-encrypt-file-example
    storing result as super_secret.txt.enc
    storing secure env variables for decryption
    

Then it will print on the console this:

openssl aes-256-cbc -K $encrypted_0a6446eb3ae3_key -iv $encrypted_0a6446eb3ae3_iv -in super_secret.txt.enc -out super_secret.txt -d

You can copy it to your .travis.yml file as I did here

Do not forget to put your .enc file on your GitHub repository.

If you have multiple files, you could zip them and then you unzip the decrypted file on the Travis ci.

For instance, you can do like this:

$ tar cvf secrets.tar foo bar
$ travis encrypt-file secrets.tar
$ vi .travis.yml
$ git add secrets.tar.enc .travis.yml
$ git commit -m 'use secret archive'
$ git push

I did it.

In my case, I had two files to use on the build of my app. So, I used this due to travis does not support multiple encrypted files. Therefore, you zip then on one file and encrypt this file.

You can have a look at my travis script here

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
2

Firebase Documentation says:

"For open source projects, we generally do not recommend including the app's Firebase config file or object in source control because, in most cases, your users should create their own Firebase projects and point their apps to their own Firebase resources (via their own Firebase config file or object)."

https://firebase.google.com/docs/projects/learn-more?authuser=0#config-files-objects

Husanboy
  • 21
  • 1
1

Firebase documentation seems to imply that there is no problem in committing the file to GitHub.

Here is an extract from the docs

The Firebase config file contains unique, but non-secret identifiers for your project. To learn more about this config file, visit Understand Firebase Projects.

Denmau
  • 231
  • 2
  • 5