react-native-dotenv
react-native-dotenv copied to clipboard
Use ENVFILE=.env.XXX with Debug/Release
I was wondering if I can control which .env is picked up by the assembleRelease/assembleDebug build processes. At the moment, it seems to me that I cannot choose which environment file is applied. Is it possible to do this:
.env.- has staging URL .env.production - has prod URL
I would like to generate a release(staging) APK that has the dev URL like so:
ENVFILE=../.env ./gradlew assembleRelease
At the moment it looks like ENVFILE is ignored and if I do assembleRelease my .env.production is picked up and if I do assembleDebug my .env file is picked up...Although react-native-config picks up the right ones ( I use that for modifying some of the values passed into Info.plist and grade.build)
Ok I think I have a solution. I modified my gradle.build file to force-feed the bundler my environment variable as set by react-native-config.
So here's what I did:
Inside my .env file I added a variable named as per the environment:
environment=development
In the grade.build file I check what it is set to (basically if not production then it must be development) and accordingly pass on the appropriate --dev argument configuration (false/true)
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
def myExtraPackagerArgs=["--dev","true" ]
if(project.env.get("environment")=='production'){
myExtraPackagerArgs= ["--dev","false" ]
}
project.ext.react = [
entryFile: "index.js",
bundleInDebug: true,
bundleInStaging: true,
extraPackagerArgs: myExtraPackagerArgs
]
Additional note about the limitation for env files.
I would like to suggest the following change to make it possible for someone to pass ENVFILE to the plugin rather than modifying the gradle file which is bound to end in tears.
basically in babel-plugin-dotenv replace platformPath and configFile with/or give precedence to/ process.env.ENVFILE over in your script when ENVFILE is defined...it's really made my life easier in having three configs:
test->staging->prod
For my purposes I just replaced configFile and platformPath with process.env.ENVFILE and pas only the name of the env file I want used.
So now I can run
ENVFILE=.env.test ./gradlew assembleRelease
and end up with a binary that has picked up it's own configurations from my env file (react-native-config) as well as a bundle with some transpiled configs (react-native-dotenv)...
most importantly though is the --reset-cache so that configs reset properly between each env's build config.
So instead of the changes made in gradle now I only have the following
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
project.ext.react = [
entryFile: "index.js",
bundleInDebug: true,
bundleInStaging: true,
extraPackagerArgs: ['--reset-cache']
]
and the modified plugin to pick up the ENVFILE as per my command line... Need to try on iOS.
Thank you!
And here's the suggested patch... a77576b1d29ab015ccd4cfbcc2ea0b3a6a6be756
For iOS, I'm seeing that at present the easiest way to specify ENVFILE is in
Build Phases -> Bundle React Native code and images -> Shell dialog
export ENVFILE=.env.staging
# needed for react-native-config to work in concert with react-native-dotenv
echo $ENVFILE > /tmp/envfile
Ideally you would want to have schemes for each type of build but I guess I'm not terribly upset just changing that one line for each type of deployment while everything else falls into place...
https://stackoverflow.com/questions/18776626/get-current-scheme-name-from-run-script-phase describes a better approach to use Xcode schemes to manage build environment
- in Production/Test/Stage schemes add the following as Build pre-actions:
echo ".env.production" > /tmp/envfile # for react-native-config
echo ".env.production" > /tmp/dotenv # for react-native-dotenv
In BuildPhases shell script read the variable back out as necessary:
export ENVFILE=$(cat /tmp/dotenv)
Remember to clean your builds in between to cause a -reset-cache
Thanks @bars0um this is great!
@bars0um I have an issue using your fork and making a release build on Android, though debug builds work fine.
Path must be a string. Received undefined
Trying to debug this looks like process.env.ENVFILE
is undefined on
https://github.com/zetachang/react-native-dotenv/commit/a77576b1d29ab015ccd4cfbcc2ea0b3a6a6be756#diff-e7f4e9cc9febf61d49934276e91477abL18
this is the /app/build.gradle
project.ext.envConfigFiles = [
onovaDebug: ".env.onova",
onovaRelease: ".env.onova",
dropDebug: ".env.drop",
dropRelease: ".env.drop"
]
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle";
Command to make a build
ENVFILE=.env.drop cd android/ && ./gradlew assembleDropRelease
@gianpaj I normally cd into the android folder first and then run. In your case the ENVFILE is being set for the first process (the cd) and not making it to the second...
cd android
ENVFILE=.env.drop ./gradlew assembleDropRelease
AH! I think you're absolutely right. Thanks for catching that 🙏
@bars0um Hey! May I know how to use your patch?
@bars0um Hey! May I know how to use your patch?
I mainly added my fork to my dependencies as follows:
npm install bars0um/react-native-dotenv --save
Thank you @bars0um !
I install it.
After that, I do ENVFILE=.env.production react-native run-ios
and then I get this error:

Do you know this problem? Do I need any other setting?