We had a need to provide configuration to our React Native application in both the AndroidManifest.xml and within the actual JavaScript code.

Originally we used react-native-config but contrary to it's claim to apply 12-factor config principles, it doesn't support using environment variables (a .env file is not the same as an environment variable...) - this gives us some problems when we try and build using Docker in our GitLab CI container.

While we haven't implemented iOS support (yet), we have found a nice way of doing this without resorting to any crazy hacks.

manifestPlaceholders

Android already supports overriding specific variables in different build configs via manifestPlacholders. We can use this, in combination with System.getenv, to inject environment variables into our AndroidManifest.xml. Update android/app/build.gradle:

    defaultConfig {
        manifestPlaceholders = [
          GOOGLE_MAPS_API_KEY: System.getenv("GOOGLE_MAPS_API_KEY")
        ]
    }

Then update android/app/src/main/AndroidManifest.xml to use the variable:

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="${GOOGLE_MAPS_API_KEY}" />

babel-plugin-transform-inline-environment-variables

Add the dependency with either NPM or yarn:

yarn add --dev babel-plugin-transform-inline-environment-variables

And update .babelrc to include it:

{
  "presets": [
    "react-native"
  ],
  "plugins": [
    "transform-inline-environment-variables"
  ]
}

Then you can access it as you would in a Node.js application:

console.log(process.env.GOOGLE_MAPS_API_KEY)

Docker Compose

If you build in docker or docker-compose, you will need to pass your host system's environment variables through by adding them to the env config for your service:

version: '3'
services:
  build:
    environment:
      - GOOGLE_MAPS_API_KEY

GitLab CI

If you're using GitLab CI, you can set these variables in your project "CI / CD Settings":

And we're done!