199 lines
5.2 KiB
Markdown
Raw Normal View History

2016-02-22 16:19:01 -08:00
# Config variables for React Native apps
Module to expose config variables to your javascript code in React Native, supporting both iOS and Android.
Bring some [12 factor](http://12factor.net/config) love to your mobile apps!
## Usage
Declare config variables in `.env`:
```
API_URL=https://myapi.com
2016-02-24 14:16:24 -08:00
GOOGLE_MAPS_API_KEY=abcdefgh
2016-02-22 16:19:01 -08:00
```
2016-02-22 16:29:33 -08:00
Then access from your app:
2016-02-22 16:19:01 -08:00
```js
2016-02-22 16:29:33 -08:00
import Config from 'react-native-config'
2016-02-22 16:19:01 -08:00
2016-02-24 14:16:24 -08:00
Config.API_URL // 'https://myapi.com'
Config.GOOGLE_MAPS_API_KEY // 'abcdefgh'
2016-02-22 16:19:01 -08:00
```
2016-02-24 14:10:15 -08:00
### Android
Config variables set in `.env` are available to your Java classes via `BuildConfig`:
```java
public HttpURLConnection getApiClient() {
URL url = new URL(BuildConfig.API_URL);
// ...
}
```
You can also read them from your Gradle configuration:
2016-02-24 14:10:15 -08:00
```groovy
signingConfigs {
release {
storeFile file(project.env.get("RELEASE_STORE_FILE"))
storePassword project.env.get("RELEASE_STORE_PASSWORD")
keyAlias project.env.get("RELEASE_KEY_ALIAS")
keyPassword project.env.get("RELEASE_KEY_PASSWORD")
}
}
```
And use them to configure libraries in `AndroidManifest.xml` and others:
2016-02-24 14:10:15 -08:00
```xml
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/GOOGLE_MAPS_API_KEY" />
```
### iOS
2016-09-13 19:00:17 -07:00
Read variables declared in `.env` from your Obj-C classes like:
```objective-c
// import header
#import "ReactNativeConfig.h"
// then read individual keys like:
2016-09-13 19:03:19 -07:00
NSString *apiUrl = [ReactNativeConfig envFor:@"API_URL"];
2016-09-13 19:00:17 -07:00
// or just fetch the whole config
NSDictionary *config = [ReactNativeConfig env];
```
Support for `plist` files is missing. We'd love to be able to refer to config from `.env` there, but haven't found a way to support this yet. Let us know if you have ideas!
2016-02-24 14:10:15 -08:00
### Different environments
Save config for different environments in different files: `.env.staging`, `.env.production`, etc.
By default react-native-config will read from `.env`, but you can change it when building or releasing your app.
#### Android
To pick which file to use in Android, just set `ENVFILE` before building/running your app. For instance:
2016-02-24 14:10:15 -08:00
```
$ ENVFILE=.env.staging react-native run-android
```
#### iOS
Support for Xcode is still a bit experimental  but at this moment the recommendation is to create a new scheme for your app, and configure it to use a different env file.
To create a new scheme, open your app in Xcode and then:
- Click the current app scheme (button with your app name next to the stop button)
- Click "Manage Schemes..."
- Select your current scheme (the one on top)
- Click the settings gear below the list and select "Duplicate"
- Give it a proper name on the top left. For instance: "Myapp (staging)"
To make a scheme use a different env file, on the manage scheme window:
- Expand the "Build" settings on left
- Click "Pre-actions", and under the plus sign select "New Run Script Action"
- Fill in with this script on the dark box, replacing `.env.staging` for the file you want:
```
echo ".env.staging" > /tmp/envfile
```
This is still experimental and obviously a bit dirty  let me know if you have better ideas on this front!
2016-02-24 14:10:15 -08:00
2016-02-22 16:19:01 -08:00
## Setup
2016-02-22 17:27:59 -08:00
Install the package:
```
$ npm install react-native-config --save
```
Then follow the platform-specific instructions below:
### iOS
2016-02-23 16:42:53 -08:00
Link the library with [rnpm](https://github.com/rnpm/rnpm):
2016-02-23 16:07:33 -08:00
2016-02-23 16:42:53 -08:00
```
$ rnpm link react-native-config
```
2016-02-23 16:07:33 -08:00
2016-02-22 17:27:59 -08:00
2016-02-22 20:05:00 -08:00
### Android
Include this module in `android/settings.gradle`:
2016-02-22 17:27:59 -08:00
```
2016-02-23 16:07:33 -08:00
include ':react-native-config'
2016-02-22 20:05:00 -08:00
include ':app'
2016-02-23 16:07:33 -08:00
project(':react-native-config').projectDir = new File(rootProject.projectDir,
'../node_modules/react-native-config/android')
2016-02-22 17:27:59 -08:00
```
2016-02-22 20:05:00 -08:00
Apply a plugin and add dependency to your app build, in `android/app/build.gradle`:
2016-02-22 17:27:59 -08:00
```
2016-02-23 16:07:33 -08:00
// 2nd line, add a new apply:
2016-02-22 20:05:00 -08:00
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
2016-02-23 16:07:33 -08:00
// down below, add new compile:
2016-02-22 20:05:00 -08:00
dependencies {
...
compile project(':react-native-config')
2016-02-22 20:05:00 -08:00
}
2016-02-22 17:27:59 -08:00
```
2016-02-22 20:05:00 -08:00
Change your main activity to add a new package, in `android/app/src/main/.../MainActivity.java`:
2016-02-22 16:29:33 -08:00
2016-02-22 20:05:00 -08:00
```java
2016-02-23 16:07:33 -08:00
import com.lugg.ReactNativeConfig.ReactNativeConfigPackage; // add import
2016-02-22 20:05:00 -08:00
public class MainActivity extends ReactActivity {
// ...
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new ReactNativeConfigPackage() // add package
);
}
```
2016-06-16 16:15:05 -07:00
##### Advanced Setup
In `android/app/build.gradle`, if you use `applicationIdSuffix` or `applicationId` that is different from the package name indicated in `AndroidManifest.xml` in `<manifest package="...">` tag, for example, to support different build variants:
Add this in `android/app/build.gradle`
```
defaultConfig {
...
resValue "string", "build_config_package", "YOUR_PACKAGE_NAME_IN_ANDROIDMANIFEST.XML"
}
```
## Troubleshooting
### Problems with Proguard
When Proguard is enabled (which it is by default for Android release builds), it can rename the `BuildConfig` Java class in the minification process and prevent React Native Config from referencing it. To avoid this, add an exception to `android/app/proguard-rules.pro`:
-keep class com.mypackage.BuildConfig { *; }
`mypackage` should match the `package` value in your `app/src/main/AndroidManifest.xml` file.