access environment variable in React-Native AndroidManifest.xml - android

I'm new to React Native. The task at hand is to set my Google API key in AndroidManifest.xml without exposing it, when pushed to GitHub.
I set up an environment variable called API_KEY, but however I want to access it in the .xml, I get an error when trying to spin up the dev server.
So far I tried:
android:value=${env.API_KEY}
android:value="${env.API_KEY}"
android:value="${API_KEY}"
Thank you!

Based on the second comment (from kenmistry), the solution that worked for me was indeed to create a placeholder in build.gradle, but since, for whatever reason, configuring and referring a .env file did't work, I invoked my environment variables like so in build.gradle:
manifestPlaceholders = [API_KEY: "$System.env.API_KEY"]
and accessed it in the .xml as suggested by kenmistry:
android:value="${API_KEY}"

assuming that you have defined the key in your .env file, you can set that up on build.gradle as manifestPlaceholders.
android {
defaultConfig {
manifestPlaceholders = [API_KEY: "$process.env.your_key"]
}
...
}
on your AndroidManifest.xml,
android:value="${API_KEY}"

Related

In my Android app how can I define properties that won't get checked into the version control system?

I want to define an API key as property in my Adroid app written in Kotlin so that it won't get checked into github.
I have found several sources of inspiration, as in
https://medium.com/swlh/how-to-safely-store-credentials-in-android-projects-using-gradle-properties-8cf500561095
and faced errors like
Cannot get property 'xyz' on extra properties extension as it does not exist
Cannot get property 'compileSdkVersion' on extra properties extension as it does not exist Open File
but with no simple solution.
I'd like to share how I eventually implemented it. Please comment and or suggest improvements.
Create a new file secret.properties at the root of your project. This file will store properties that should remain secret. Add it to .gitignore so it won't be checked into the version control system (e.g. github).
In addition, we want to be able to set or overwrite those properties with using environment variables.
Add a buildscript at the top of your app's build.gradle to read the secret.properties file.
Call buildConfigField() in the defaultConfig section. You must provide a string wrapped inside escaped double quotes (see example here).
build.gradle
buildscript {
Properties properties = new Properties()
def propertiesFile = rootProject.file('secret.properties')
if (propertiesFile.exists()) {
properties.load(propertiesFile.newDataInputStream())
}
def localPropertyValue = properties.getProperty('custom.variable')
def systemEnvValue = System.getenv('CUSTOM_VARIABLE')
rootProject.ext.custom_variable = systemEnvValue != null ? systemEnvValue : localPropertyValue
}
plugins {
...
}
android {
...
defaultConfig {
...
buildConfigField("String","CUSTOM_VARIABLE", "\"${rootProject.ext.custom_variable}\"")
}
...
}
secret.properties
custom.variable=my_custom_variable_value_here
Remember to click on the "Sync now" button at the top of your build.gradle file after you've edited and saved it.
Finally, rebuild your project and the new property becomes available using BuildConfig.CUSTOM_VARIABLE throughout your code.

How to configure Azure AD B2C for different environments in Android

I am using Azure AD B2C and need a different configuration file for each environment. I expect to have multiple B2C Tenants for my app. One for each environment. That means I need to alter my calls to reference different files. Currently I am calling:
PublicClientApplication.createMultipleAccountPublicClientApplication
Where the second parameter is an:
int configFileResourceId
I have been using:
R.raw.auth_config_multiple_account
But now I need to fold in additional environments. I handle most/all of my environment changes in the build.gradle like this:
buildTypes {
release {
buildConfigField "String", "SERVER_URL", '"xxx.xxxx.com"'
}
debug {
buildConfigField "String", "SERVER_URL", '"yyyy.yyy.com"'
}
}
But how do I do this while referencing the file itself? I can use the R.raw.auth_config_multiple_account from anywhere, but cannot from the build.gradle. How are others doing this? It's also very convenient to reference it from anywhere.
• I would suggest you to reference the build.gradle file for any environment changes by calling the System.env(“variable name”) which works in gradle to get the path of any variable. Thus, this should get you the actual path of the folder which contains this file.
• So, to reference the build.gradle file in the variable, it needs to be exported to a location like as below shown as an example: -
home = System.getenv(‘HOME’) OR "${System.env.HOME}/something/plugins"
• Once it is exported and called as above, you can edit it for adding or modifying any of your environment changes in the build.gradle file.
Please find the below links for more information: -
how to use Environment Variables in Gradle build files?

Kotlin DSL add new sourceSet

On Gradle 6.1.1, how to go around adding sourceSets for android project?
The answer on other questions doesn't work anymore, getByName("name") returns error with SourceSet with name 'main' not found.
The official document said to use
sourceSets {
main {
java {
srcDir("thirdParty/src/main/java")
}
}
}
However, there are over 20 main that has to be imported and I'm not sure which one is correct.
I'm using gradle 6.5.1, however documentation suggest, that is should also work for you, try:
sourceSets {
named("main") {
java.srcDir("../buildSrc/src/main/java")
}
}
It's also works for build types (debug/release), flavours etc.
Reason for this is that groovy can somehow interpret itself and knows main etc., but on gradle kts, you have call it using named for already existing, or getByName, create etc. base on need.
Similiar situation is for implement and api in groovy you can just use implementationDebug to attach it only for debug version, but in kotlin dsl you have to call it as a string "implementationDebug", because there is no such function
----- PS -----
If named, getByName not works for you, then try to experiment with findByName and create

How to mock Gradle's buildConfigField for Travis CI build?

I try to integrate my android app with a Travis CI. My app need an api key, that shouldn't be posted in repo. So, i put my api key in global gradle properties file ~/.gradle/gradle.properties:
MY_SECRET_API_KEY="aaaabbbcccdddeeefff"
Then I read this value in app/build.gradle file (which is in public repository) and set it as buildconfig field:
apply plugin: 'com.android.application'
android {
// ...
buildTypes.each {
it.buildConfigField "String", "API_KEY", MY_SECRET_API_KEY
}
// ...
}
and use this api key in app code by accessing to BuildConfig.API_KEY.
I get following error message from Travic CI:
Could not find property 'MY_SECRET_API_KEY' on com.android.build.gradle.AppExtension_Decorated.
Use Travis' environment variables; more specifically use encrypted variables so that the values of secure variables are always masked in the build output. You read Tavis env variables in the gradle script as System.getenv('key') though. It is cleaner to use environment variables on the local end as well. If you want to still use gradle.properties, you could do something like this:
hasProperty('secret_api_key') ? secret_api_key: System.getenv('secret_api_key')
To set Travis env variables, see here:

Could not find property 'xxxx' on com.android.build.gradle.AppExtension_Decorated

I got this error after I added these lines to my gradle file:
buildTypes.each {
it.buildConfigField 'String', 'OPEN_WEATHER_MAP_API_KEY', MyOpenWeatherMapApiKey
}
then the log show:
Could not find property 'MyOpenWeatherMapApiKey' on com.android.build.gradle.AppExtension_Decorated#c3b784
The solutions on google that I searched cannot solve my problem. Please show me where I was wrong?
Since you are using a String you have to use this syntax:
buildConfigField "String" , "OPEN_WEATHER_MAP_API_KEY" , "\"XXXXX-XXXXX-XXX\""
The last parameter has to be a String
Otherwise you can use something like this:
resValue "string", "OPEN_WEATHER_MAP_API_KEY", "\"XXXXX-XXXXX-XXX\""
The first case generates a constants iin your BuildConfig file.
The second case generates a string resource value that can be accessed using the #string/OPEN_WEATHER_MAP_API_KEY annotation.
You should define MyOpenWeatherMapApiKey in your local user settings, so, go to your home gradle settings: ~/.gradle/gradle.properties (Win: %USERPROFILE%\.gradle\gradle.properties). If gradle.properties does not exist - just create it.
In the file add following line:
MyOpenWeatherMapApiKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
(unfortunately, Android Udacity teachers were not very nice to explain how does it work from gradle perspective; as same as I've not easily found any documentation from gradle how it.buildConfigField works)
The 'OPEN_WEATHER_MAP_API_KEY' references a gradle property named 'MyOpenWeatherMapApiKey' that needs to be configured.
One reason is for the build system to generate the code for this. Another might be so that you don't accidentally commit your API-KEY to GitHub or other public repo.
What you should do is add an entry to your 'gradle.properties' file like this:
MyOpenWeatherMapApiKey="[YOUR-API-KEY]"
Then sync your project with gradle (if using Android Studio)
See " Open Weather Map API Key is required." at the bottom of https://github.com/udacity/Sunshine-Version-2
Sign up account at http://openweathermap.org/appid#use or other weather api providers to get your unique API Key
Go to your home gradle settings: ~/.gradle/gradle.properties
Add this line:
MyOpenWeatherMapApiKey="yourUniqueApiKey"
Rebuild it
I had to use a little information from multiple answers on here to fix this issue.
it.buildConfigField 'String', 'OPEN_WEATHER_MAP_API_KEY', MyOpenWeatherMapApiKey is fine. The top voted answer puts the key directly into this field rather than referencing a "global" key for your user.
You need to acquire a Open Weather Map API Key by making an account here
Gradle expects you to put the key that you get from creating an Open Weather Map account into a field named MyOpenWeatherMapApiKey that is referenced by OPEN_WEATHER_MAP_API_KEY from before. To do this, open gradle.properties in Android Studio and add MyOpenWeatherMapApiKey="<Your Key Here>"
Now you should be able to build the app with no issues.
The accepted answer is absolutely correct. Another way, probably simpler, to format the value inside as the String is like this:
it.buildConfigField 'String', 'OPEN_WEATHER_MAP_API_KEY', '"xxxxxxxxxxxxxxxxxx"'

Categories

Resources