DEV Community

Cover image for How to manage staging and production environments in React Native

How to manage staging and production environments in React Native

Calin Tamas on February 19, 2019

Your life as a React Native developer is just about to get easier. At least mine did, as soon as I learned how to manage staging and production env...
Collapse
 
bobrundle profile image
Bob Rundle

Had to add matching fallbacks to my custom releases to get this working on Android.

    stagingrelease {
        initWith release
        matchingFallbacks = ['release', 'debug']
    }
    productionrelease {
        initWith release
        matchingFallbacks = ['release', 'debug']
    }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
bobrundle profile image
Bob Rundle • Edited

Spent quite some getting env files to switch with build type. Discovered that you need to apply dotenv.gradle after envConfigFiles are defined.

project.ext.envConfigFiles = [
    debug: ".env",
    release: ".env",
    stagingrelease: ".env.staging",
    productionrelease: ".env.production"
]
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
Collapse
 
luizfbrisighello profile image
Luiz Felipe Shimizu Brisighello

In Android Studio there is no Build Variants for me at:
View -> Tool Windows

For some reason im not able to call a env variable as a path in like:
require(env.IMAGE_SOURCE_PATH)

Any ideas?

Collapse
 
waqaramjad profile image
Waqar Amjad

i have same issue

Collapse
 
calintamas profile image
Calin Tamas

Might be something related to react-native-config linking. Try reinstalling the lib

Collapse
 
jake41 profile image
jake41

ENVFILE=.env.staging react-native run-ios

This step is giving me error:

/node_modules/react-native-config/ios/ReactNativeConfig/ReactNativeConfig.m:2:9: fatal error: 'GeneratedDotEnv.m' file not found

import "GeneratedDotEnv.m" // written during build by BuildDotenvConfig.ruby

Collapse
 
smakosh profile image
smakosh

I have solved that here: github.com/luggit/react-native-con...

Collapse
 
calintamas profile image
Calin Tamas

It looks like an issue with react-native-config linking.
Check here: github.com/luggit/react-native-con...

Collapse
 
mahesh__nandam profile image
Mahesh Nandam

I succeed to solve this by removing react-native-config from Pod file and manually linking.

Collapse
 
teeccblog profile image
Teecc blog

So schemes in xcode are working for you?? i've always got errors building in custom schemes in xcode ever since i started working with RN. Actually i used this library in a time, that was suposed to solve the issue i mention github.com/thekevinbrown/react-nat...
Unfortunately it is not working for me any more -_-

Collapse
 
calintamas profile image
Calin Tamas

What exactly isn't working on your side?

Collapse
 
teeccblog profile image
Teecc blog

I am having the same error i've ever had: when i try to build in my custom scheme config, this error arises: apple mach-o linker error. When i switch back to release/debug it works again, so the problem relies on my custom schemes. I've seen some posts where people suggest to change some of the build variable folders, so the custom scheme seeks for resources in the release-build folder instead of the custom one. But it didn't work for me either.. I was just wondering if you had to perform an extra-step/configuration to make custom schemes work in your xcode-RN project.

Thanks for the reply,
Cheers

Thread Thread
 
calintamas profile image
Calin Tamas

Hi, not really. Just make sure to have the correct target for build on the new scheme.

Also, it's easier to just duplicate the default scheme when creating a new one.

Collapse
 
suleiman365 profile image
Suleiman Ahmed

Great tutorial, Calin.

Small issue, please.

"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:"

The above step doesn't seem to work for me. Perhaps, I'm doing something wrong on the Android front. When I do the above, I noticed that the newly added release configs (i.e productionrelease or stagingrelease) doesn't show in the dropdown of the other third party native packages, such as 'react-native-config', for example. And when I go ahead to select, say, 'stagingrelease', I get this error: ERROR: Unable to resolve dependency for ':app@stagingrelease/compileClasspath': Could not resolve project :react-native-gesture-handler and this: ERROR: Unable to resolve dependency for ':app@stagingreleaseUnitTest/compileClasspath': Could not resolve project :@react-native-community_async-storage.
And so on (listing all my third party packages).

Thanks.

Collapse
 
bobrundle profile image
Bob Rundle

This is the same problem I had. You need to have fallback build type because you have other projects for which staging and production releases are not defined. See my post in these comments.

Collapse
 
jadhavrahul10 profile image
rahul

Hi,
Actually i want to setup 3 env. i.e dev, stage (Flavor) ,prod( release ) and
1.for dev it's debuggable by default
2.for stage i want to setup debug.keysore (for debugging ) and release.keysore (for release testing we can se pre prod ) different
3.And prod release i want different prod.keystore how can i manage this thing.

hoe can i mange this things in buildTypes , productFlavors , signingConfigs?

Collapse
 
amandine16 profile image
Amande

I couldn't get the environment variables on android. There was a step missing.
In the file android/app/build.gradle, you have to add a line that is not indicated in the tutorial.

The tutorial is very complete.

This line was missing: apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle "

I had to insert it after project.ext.envConfigFiles and my other plugin apply ... Otherwise it didn't work.

Hopefully I helped someone =)

Here are the first lines of code in android/app/build.gradle

project.ext.envConfigFiles = [
debug: ".env",
release: ".env",
stagingrelease: ".env.staging",
productionrelease: ".env.production"
]
apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services'
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
import com.android.build.OutputFile
...

Collapse
 
jotahws profile image
João Henrique Wind

Just a heads up for those trying to do this in a newer version of react-native-config.
According to the docs, the new Script Action for the iOS scheme should be the following:

cp "${PROJECT_DIR}/../.env.staging" "${PROJECT_DIR}/../.env"

and NOT

echo ".env.staging" > /tmp/envfile

Reference:
github.com/luggit/react-native-con...

Collapse
 
jaapweijland profile image
Weijland

Note that since v 2.148.0 of Fastlane the follow line:

fastlane ios beta --env=production

should be

fastlane ios beta --env production

Collapse
 
jadhavrahul10 profile image
rahul

How to manage firebase ( google-service.json and google-service-info.plist ) for android & ios for load configuration as per there env file parameter

Collapse
 
calintamas profile image
Calin Tamas

Hi, rahul

on Android you can have both config files stored somewhere in your app source

config/firebase/production/google-services.json
config/firebase/staging/google-services.json

And write a bash script that copies these files in the android folder at build time (run the script with fastlane):

#!/usr/bin/env bash

if [ "$IS_PRODUCTION" == "true" ];
then
  echo "Setting Firebase production environment"
  yes | cp -rf "../js/config/firebase/production/google-services.json" "../android/app"
else
  echo "Setting Firebase staging environment"
  yes | cp -rf "../js/config/firebase/staging/google-services.json" "../android/app"
fi

and on iOS, add both files to the Xcode project

GoogleService-Info-production.plist
GoogleService-Info-staging.plist

In AppDelegate.m, select the correct file for your env

NSString *isProduction = [ReactNativeConfig envFor:@"IS_PRODUCTION"];
NSString *firebaseConfig = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info-staging" ofType:@"plist"];
  if ([isProduction isEqualToString:@"true"]) {
    firebaseConfig = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info-production" ofType:@"plist"];
  }
Collapse
 
jadhavrahul10 profile image
rahul

How could i generate build android and for IOS as per env param?

Collapse
 
giacomocerquone profile image
Giacomo Cerquone

Hi, let me know what do you think about my alternative solution: dev.to/giacomocerquone/re-thinking...

Collapse
 
calintamas profile image
Calin Tamas

Nice way of doing it!

My reason for using react-native-config was that I needed to access the env vars inside the native projects as well.

Collapse
 
giacomocerquone profile image
Giacomo Cerquone

Well in that case yes, it's a must :)

Collapse
 
sauloaguiar profile image
Saulo Aguiar

Hey Calin!
Thanks for coming up with this tutorial!
After I replicated the steps, I wasn't getting any error but my .env.staging file wasn't being read.
I noticed in your github repo that for the android project there's an apply rule for the react-native-config project in the buidl.grade file.

apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"

Collapse
 
praveens96 profile image
praveens96

need to do add Library Search paths in-order get it working, for me I have Realm, YouTube etc libraries for which .a files were in Linked libraries. I was getting ld: library not found -lRealmJS error.

so, I followed: stackoverflow.com/a/40661027/4065202 to resolve the issue

Collapse
 
wkwyatt profile image
William

Do you have an example of the script you used to run the env variable setup for the iOS schemes? I check the GitHub project and it wasn't there.