react-native-dotenv: APP_ENV doesn't work as expected

I want to be able to use development and production config files according to the APP_ENV variable I pass.

But even if I pass the env as a variable, it uses development for debug and production for release.

"android": "APP_ENV=development react-native run-android --variant 'devDebug'",
"android-prod": "APP_ENV=production react-native run-android --variant 'prodDebug'",
"build-android-dev": "cd android && APP_ENV=development ./gradlew assembleDevRelease",
"build-android": "cd android && APP_ENV=production ./gradlew assembleProdRelease",

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 6
  • Comments: 19 (10 by maintainers)

Most upvoted comments

@caiangums Thanks for the motivation to help. I think all of us read the documentation, and we all provided the APP_ENV variable to the react-native start command. That’s essentially the source of the problem. Please re-read my above comment and check how release versions are built. Release versions on Android spawn their own packager if bundleInYourCustomName is set to true in app/build.gradle. Therefore, because it internally spawns it’s own packager, you are unable to provide any env variables, like APP_ENV dynamically from scripts.

I ended up using react-native-config because of the following reasons:

  • I’ve had no caching issues with that package (which drove me crazy with this)
  • I can use the environment variables from native code as well, and I only have one .env file as configuration
  • It provides APP_ENV alternative to react-native run-android command and not the react-native start command, hence the issue I described above is non-existent.

Anyway, thanks @goatandsheep for your work and your kindly responses, I just found that the other package better suits my needs.

Hey! 👋

I noticed that you are passing the APP_ENV variable at the react-native run-android command when it should be passed at the starting of the metro server(react-native start). It is possible to see that in this section of the README.md.

I suggest changing your scripts section in your package.json to something like:

{
  "scripts": {
    "start": "APP_ENV=development react-native start --reset-cache",
    "start-prod": "APP_ENV=production react-native start --reset-cache"
  }
} 

It is important to note that your .env files should respect the pattern .env.<environment>. So, I also suggest changing your main/production .env file to .env.main or .env.production, so you could pass them as APP_ENV=main or APP_ENV=production 😄

Hope that helps!

Hey, thank you for opening this issue! 🙂 To boost priority on this issue and support open source please tip the team at https://issuehunt.io/r/goatandsheep/react-native-dotenv/issues/131

Hi @Asranov! Turns out that I changed my approach to other libs for solving this issue.

If you want, you can try the approach mentioned by @f4z3k4s using react-native-config.

If you’re using APP_ENV, you should avoid using development nor production as values and you should avoid having a .env.development nor .env.production. This is a Babel and Node thing that I have little control over unfortunately and is consistent with many other platforms that have an override option, like Gatsby. If you want to use development and production, don’t use APP_ENV as it’s built in. Use NODE_ENV=development or NODE_ENV=production.

This has been added to the README.

I need to figure out how the other library deals with caching issues

@f4z3k4s Thanks for the clarification! I used react-native-config before but the approach from this library seems easier to configure 🙏

While trying to change some code at metro.config.js to properly pass the actual values, no success was accomplished from my side. Hope that @goatandsheep could give a better solution 😅

The problem I ran into using APP_ENV:

As I understand APP_ENV should be provided to the packager, not the run-android command. So if I run APP_ENV=staging npx react-native start it uses .env.staging as a result.

That is all good if you have the ability to spawn a custom packager, e.g.: in debug builds. But what happens when you run a release build? If bundleInStaging in app/build.gradle is set to true, it will spawn a custom packager during the build process, regardless if you have a packager running with the proper APP_ENV set. And in the custom packager’s environment, APP_ENV will be unset. If you set bundleInStaging to false and you try to build your own bundle with APP_ENV=staging npx react-native bundle ... it still spawns it’s own packager, and the env you specified for the bundle command doesn’t apply for the packager. So all in all, APP_ENV is unusable for release builds according to my understanding.

Am I missing something or do you experience the same?

I managed to bypass this whole APP_ENV issue by creating a short node script which copies the content of .env.staging to .env before build and .env gets picked up by the bundle in release as well. I am using .env.debug, .env.staging and .env.release and based on the desired release, I dynamically copy the contents of these to .env.

btw, you shouldn’t need APP_ENV for production and development as those are built in. You’re better off controlling it through the variants inside your gradlew

@goatandsheep unfortunately no change