How to manage staging and production env for React Native App
In this blog will demonstrate you guys how to manage your React Native App with different env, staging and production. This help me a lot when I want to change my environment to debug or release my app to the Store.
First thing first, we are going to use one of config file library, react-native-config. After following the docs, if you are using podfile you will face the following error:
/node_modules/react-native-config/ios/ReactNativeConfig/ReactNativeConfig.m:2:9: fatal error: ‘GeneratedDotEnv.m’ file not found
To solve it just open your podfile, then at the bottom of your podfile please add the following codes and then run pod install:
post_install do |installer|installer.pods_project.targets.each do |target|if target.name == “React”target.remove_from_projectendif target.name == ‘react-native-config’phase = target.project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase)phase.shell_script = “cd ../../”\“ && RNC_ROOT=./node_modules/react-native-config/”\“ && export SYMROOT=$RNC_ROOT/ios/ReactNativeConfig”\“ && export BUILD_DIR=$RNC_ROOT/ios/ReactNativeConfig”\“ && ruby $RNC_ROOT/ios/ReactNativeConfig/BuildDotenvConfig.ruby”target.build_phases << phasetarget.build_phases.move(phase,0)endendend
Next, I am going to create 3 files in my root project
// .env
API_HOST=https://api.staging.foobar.com
// .env.staging
API_HOST=https://api.staging.foobar.com
// .env.production
API_HOST=https://api.foobar.com
Note: please follow the above convention, no space needed
Now, to put those vars to use for my React Native app, here’s how my config file usually looks like:
// import wherever you want to use your config vars
import env from 'react-native-config'const API_HOST = config.API_HOST;
That’s all. By default, react-native-config
reads from the .env
file, but reading from any file & running the project is possible via the following command:
$ ENVFILE=.env.staging react-native run-ios
All good so far, but I want my build process to be as automated as possible. So manually specifying the .env
file is not acceptable. Avoiding this is what we're going to do next.
IOS SETUP
On iOS, I’m going to take advantage of the concept of schemes.
go to your XCODE -> PRODUCT -> EDITSCHEMA -> DUPLICATESCHEMA
After duplicating schema I am going to create another new schemas, naming is very important as my default schema is pick_up so I am going to create another two schemas called pick_up.staging and pick_up.production
Next to ensure that my schema loads up .env
file I want, I am going to select my pick_up.staging schema and then expand run section -> click on Pre-action -> click on + button and then choose New Run Script Action and add the following script
echo “.env.staging” > /tmp/envfile
for pick_up.production we are going to do the same step as pick_up.staging by just selecting pick_up.production and add the following script
echo “.env.production” > /tmp/envfile
Note: When you want to change your environment, you just select your schema (staging or production) and then build. However, when you first build, sometimes, It won’t change your environment yet so you need to do it twice and to ensure that just console.log(your config var).
That is the end of IOS setup let move to another funny setup for Android
ANDROID SETUP
For Android, we have build types. So in your android/app/build.gradle, under apply plugin: “com.android.application" please add
project.ext.envConfigFiles = [
debug: ".env",
release: ".env.production"
]
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
To run the app using one of the build types defined above, go to View -> Tool Windows -> Build Variants
and select the variant (in the newly exposed window) before building:
Finally we completed all steps for both IOS and Android. For your sensitive key please do not commit to your repository, eg(.env.staging and .env.production).