Configuring Environment Settings for Production and Development in React-Native Applications
I have been working on building an app in react-native which shares a back-end with a web app built in React, using the awesome react-on-rails project.
All of the projects I have worked on in React and Rails use 12-factor to manage environment state, but this does not seem to be a problem that is elegantly solved in React Native.
We wanted a way to build the native iOS app such that it would have the correct environment settings (like the app server it needs to talk to) built into the deployment of the app without hard-coding values into the project itself.
Unfortunately, using Xcode build settings to do this is not intuitive. React-Native only knows about Debug and Release build configurations, so if you add another one to your project, say ‘Staging,’ you will quickly discover that your project no longer builds. Adding a new build configuration name will cause the React Native build steps to output a Release build, and your project will most likely not be able to find the required header files and binaries.
There are a couple ways to get around this:
(1) Manually set an include path for React Native header files and linked libraries [click here]
(2) Use the react-native-schemas-manager package in your project
(3) Cook up your own scripts to copy the Debug or Release configurations into your configurations as appropriate
(4) Use something like react-native-config. This purports to manage a local .env file for both Android and iOS. I tried and tried but I could not get this to work
Needless to say, (3) was right out. See the references section below for some examples of people who did this.
(2) performs some scripting magic on your project to make sure that all of the default project settings you get when you create your React Native project will be copied to your new build configurations.
At first, I went with (1). This solution works but there is a lot of hard-coding of paths and such that you will need to do, and this will definitely not make it easy to on-board people to your project long term. Also you may encounter some trial and error yak shaving while you figure out where everything needs to be for your project to build successfully. By the way, if you want to know where Xcode is putting all of your build files, click here. Check out the resulting Xcode project here.
After trying react-native-schemas-manager (3) I have to say this is by far the best solution. I published a git repository here that contains a bare-bones React Native project and a sample configuration. So far this has been working really well. I also added a native class implementation that loads environment settings from the project plist file, so that once you have multiple build configurations, you can simply build a different version of your app for each environment, and have your React Native app pick up the correct settings from a JSON file you keep in your project (but not in source control). Then include appConfig.js in your project files as needed, and this gives you an object with the correct configuration for the environment in which you are running.
References:
[Multunus](http://www.multunus.com/blog/2016/06/automated-environment-management-react-native-ios/)
[Facebook Issues List](https://github.com/facebook/react-native/issues/11813#issuecomment-273279257)