DEV Community

Cover image for Hide your api keys from your android manifest file with Flutter using local.properties
Steve
Steve

Posted on • Updated on

Hide your api keys from your android manifest file with Flutter using local.properties

A common problem we face is the protection of out private data such as API keys.
When working with Flutter, you may need to integrate a third party service which requires you to add your API key to your manifest file.

You wouldn't want to check-in your API keys to the source code. Instead, you would like to embed them into an internal file ignored by your source control and use them through your app. For Android there's already a standard file that's used for this purpose called local.properties.

The AndroidManifest.xml is an xml file thus we cannot write scripts there. Instead, we can write a small script in build.gradle file, read api key from the local.properties file and assign it to a variable. AndroidManifest will be able to read that variable.

Let's dive into the code!

Assuming we want to integrate segment, we would need to add the write key toe our AndroidManifest.xml file, instead of writing the clear API key, we would write :

<meta-data android:name="com.claimsforce.segment.WRITE_KEY" android:value="${segmentWriteKey}" />
Enter fullscreen mode Exit fullscreen mode

And then register the API Key in the local.properties file under the variable named "segment.writeKey" like:

sdk.dir=
flutter.sdk=
flutter.buildMode=debug
flutter.versionName=1.0.0
flutter.versionCode=1
segment.writeKey=<SEGMENT API KEY GOES HERE> # We've added this line
Enter fullscreen mode Exit fullscreen mode

segmentWriteKey is the name of the variable we are going to create in the module level build.gradle (android/app/build.gradle).

Add these lines before android{} :

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def segmentWriteKey = properties.getProperty('segment.writeKey') // Notice we get the property we the exact same name we wrote in the local.properties file
Enter fullscreen mode Exit fullscreen mode

This should look like :

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream()) 
def segmentWriteKey = properties.getProperty('segment.writeKey')

android {
    compileSdkVersion 28
    ...
}
Enter fullscreen mode Exit fullscreen mode

Under the android section, in the defaultConfig, add this line to the end:

manifestPlaceholders = [segmentWriteKey: segmentWriteKey]
Enter fullscreen mode Exit fullscreen mode

Now everything should look like:

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def segmentWriteKey = properties.getProperty('segment.writeKey')

android {
    ...
    defaultConfig {
        ...
        manifestPlaceholders = [segmentWriteKey: segmentWriteKey]
    }
    ...
}
Enter fullscreen mode Exit fullscreen mode

Note that the local.properties file is ignore by the source control by default so you will not have to do it yourself (but prevention is better than cure ;) ).

Well, we are done.
Hope this article helped you and see you on another one.
Thanks for reading.

Top comments (7)

Collapse
 
hjhl profile image
HJHL

Good job! It works for me.

Collapse
 
nb9960 profile image
Nishtha Bodani

How to delare it in yml so that github actions run properly?

Collapse
 
no2s14 profile image
Steve

You can add a step in your build job like this :

jobs:
    build: 
        # your other scripts here...
        - name: Inject local.properties value
               env:
                     VALUE: ${{ secrets.VALUE }}
                     run: echo VALUE="$VALUE" > ./local.properties
Enter fullscreen mode Exit fullscreen mode
Collapse
 
uchihasharukh profile image
uchihasharukh

how to access this key in the app??

Collapse
 
no2s14 profile image
Steve • Edited

You will need to write plateform channels to do that.
Since we've declared a variable in our gradle, it will be avaible for use in Java/Kotlin under the BuildConfig class.

Collapse
 
febryardiansyah profile image
Febry Ardiansyah

how about the iOS?

Collapse
 
no2s14 profile image
Steve

These variables on iOS side are generally used in the AppDelegate class. It's then easy for you as a developer to hide their values:

  • Through dart define
  • Through a .env file