Skip to main content

Supporting multiple environments (.env)

Most companies usually go through multiple environments, such as production, staging, and development environments. This chapter will explain how to implement a .env configuration inside your react native application to support multiple environments.

Warning

It is not recommended to commit any sensitive information in the .env file to code in case your git repo is exposed. The best practice is to put a .env.template or .env.development.template that contains dummy values, so other developers know what to configure. Then add your .env and .env.development to .gitignore.

Installing react-native-config:

yarn add react-native-config

After the installation, run the setup for iOS.

cd ios && pod install && cd ..

Setup for android:

  • Add the below line of code to apply the plugin:
android/app/build.gradle
apply plugin: "com.android.application"

+ apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
  • Create three files in root folder of the project .env.development, .env.staging & .env.production which will contain our environment variables.
// .env.development
API_URL=https://myapi.development.com

// .env.staging
API_URL=https://myapi.staging.com

// .env.production
API_URL=https://myapi.com

  • Now we need to define envConfigFiles in build.gradle, associating builds with env files. To achieve this, add the code below before the apply from call, and leave the build cases in lowercase.
android/app/build.gradle
+ project.ext.envConfigFiles = [
+ productiondebug: ".env.production",
+ productionrelease: ".env.production",
+ developmentrelease: ".env.development",
+ developmentdebug: ".env.development",
+ stagingrelease: ".env.staging",
+ stagingdebug: ".env.staging"
+ ]

apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
  • Next, add productFlavors in build.gradle, just below buildTypes.
android/app/build.gradle
    buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.debug
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}

+ flavorDimensions "default"
+ productFlavors {
+ production {}
+ staging {
+ // We can have build-specific configurations here. Like using applicationIdSuffix to create different package name (ex. ".staging")
+ }
+ development {}
+ }
  • Names should match based on productFlavors, so productiondebug will match debug in this case and generate debug build of the App with configuration from .env.production.

Also add matchingFallbacks in buildTypes as shown below:

android/app/build.gradle
    buildTypes {
debug {
signingConfig signingConfigs.debug
+ matchingFallbacks = ['debug', 'release']
}
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.debug
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
  • Add in your package.json these scripts:
package.json
+ "android:staging": "react-native run-android --variant=stagingdebug",
+ "android:staging-release": "react-native run-android --variant=stagingrelease",
+ "android:dev": "react-native run-android --variant=developmentdebug",
+ "android:dev-release": "react-native run-android --variant=developmentrelease",
+ "android:prod": "react-native run-android --variant=productiondebug",
+ "android:prod-release": "react-native run-android --variant=productionrelease",

  • Now, to have a debug build with development environment, run:
yarn android:dev

  • Or to have a production build with release mode, run:
yarn android:prod-release

Setup iOS:

  • In iOS, we'll build three new schemes called TestAppDevelopment, TestAppStaging, and TestAppProduction, each containing configuration files for the appropriate environments of development, staging, and production.

  • Open the project in Xcode by running open ./ios/MyApp.xcworkspace and perform the following steps to create schemes: Go to Product > Scheme > Edit Scheme in the Xcode menu. .env setup ios step 1

  • Click Duplicate Scheme on the bottom, name it MyAppDevelopment, and check the shared checkbox. The previous actions will be repeated twice more (for MyAppStaging & MyAppProduction).

    .env setup ios step 1 .env setup ios step 1

  • Now inside edit schemes, select the new generated scheme and then expand Build settings in the sidebar, select Pre actions, and under the plus sign, select New Run Script Action`. .env setup ios step 1

  • Select the project from the Provide build settings from the dropdown

  • Where it says Type a script or drag a script file, type:

cp "${PROJECT_DIR}/../.env.staging" "${PROJECT_DIR}/../.env"  # replace .env.staging for your file

.env setup ios step 1

  • Do the same steps as the other generated schemes.

  • Add the scripts to package.json:

package.json
  "ios:dev": "react-native run-ios --scheme 'MyAppDevelopment'",
"ios:dev-release": "react-native run-ios --configuration Release --scheme 'MyAppDevelopment'",
"ios:prod": "react-native run-ios --scheme 'MyAppProduction'",
"ios:prod-release": "react-native run-ios --configuration Release --scheme 'MyAppProduction'",
"ios:staging": "react-native run-ios --scheme 'MyAppStaging'",
"ios:staging-release": "react-native run-ios --configuration Release --scheme 'MyAppStaging'",
  • Now, to have a build with the development environment, run:
yarn ios:dev

And it will run the application with development configuration.

Accessing environment variables:

  • Once everything is set up, we can access the variables as follows:
import Config from "react-native-config";
Config.API_URL;
//`https://myapi.development.com`

Sources:

https://www.npmjs.com/package/react-native-config