React Native Expo Environment Variables with EAS - react-native

I have a secret key that I need to use in my app. On the web, I would use a .env file, but with React Native and Expo.
I want to use the EAS Build, and found the following documentation EAS variables docs
This gives information about adding the "secret" to your eas.json file, but I am unable to find 2 important things:
What code to use to access the secret variable in the dev and prod environment.
I'm thinking in production the code would be 'process.env.SECRET_KEY' and hoping the same code would apply for the dev environment, but I am not sure how to get the process.env in dev to be populated with the SECRET_KEY.
When I console.log(process.env) in my app, I just get NODE_ENV: "development".
My thought is that many apps need some sort of Secret bit of info, so any ideas on a best practice or at this point just any way to get this to work!

I was able to get the environment (secret) variable working with the eas build process.
I am sure there are other ways to accomplish this, however this is the approach I took:
I chose to use a .env file for the dev environment and the eas secret:create command for eas builds.
First, you need to create a secret for your project with the eas cli.
eas secret command
Then, create you .env file with your secret. Make sure this has the same spelling as the secret created for eas.
You will then use the app.config.js file to inject the secret so that your code can access it. NOTE: I found that I needed to remove the app.json file. I moved all the config from app.json to app.config.js.
Also remember to run npm install dotenv on your terminal to add dotenv to your project.
// the dotenv/config will read your .env file
// and merge it with process.env data
// This is just for the builds that happen outside of eas
import "dotenv/config";
// the secrets created with eas secret:create will
// be merged with process.env during eas builds
const secretKey = process.env.SECRET_KEY;
export default {
name: "TV Tracker",
slug: "tv-tracker",
scheme: "tvtracker",
...
// THIS IS WHAT WE READ IN THE CODE
// uses the expo constants package
extra: {
secretKey: secretKey,
},
};
Now we can read the secretKey using the expo-constants module.
import Constants from "expo-constants";
...
let secretKey = Constants.expoConfig.extra.secretKey;

Got my answer here
https://github.com/expo/eas-cli/issues/1265#issuecomment-1301525320
I do wish expo simplified/cleaned their documentation a bit and made like one simple example which just works out of the box instead of providing tons of information where it's so easy to miss Constants.expoConfig vs Constants.manifest

As a follow-up to #markmccoid's answer, I usually use a bash script to put the .env secrets into eas for the project.
while IFS='=' read -r key value; do
eas secret:create --scope project --name "$key" --value "$value"
done < .env

Related

How can I use environment variables if I use vuejs with CDN?

I was using Vuejs CDN to develop my app. Now, I want to separate dev and prod since the API endpoints are separated. I don't want to expose my dev API endpoint. How can I do it with the simplest way?
I tried to use dotenv. Put the DEBUG variable in .env.
var debug = process.env.DEBUG;
console.log(debug);
Vue.directive('focus', {
inserted: function (el) {
el.focus()
}
})
var vm = new Vue({...
My .env file
DEBUG=true
I can read the debug variable. However, it gives an error of "Vue is not defined" since I didn't install Vue with npm. Or I must install Vue with npm?
If you're using Vue CLI, facilities for this are already built in in the form of .env files. You'd create .env.dev and .env.production files (and probably a .env.local for local development), containing:
VUE_APP_ENDPOINT=https://...
Which in your Javascript files you can access as:
const endpoint = process.env.VUE_APP_ENDPOINT;
Then you create different builds for your two different environments:
vue-cli-service build --mode dev # or --mode production
The variables will be baked into the build, so your two different builds only contain their respective endpoints.

Use .env variables to set up appcenter on a react-native app

I started using MS appcenter in my bare react-native app, and during the set up they ask me to add two new files to the project:
For IOS: AppCenter-Config.plist with
<dict>
<key>AppSecret</key>
<string><MY_SECRET_KEY></string>
</dict>
And for Android I need to add a JSON file with the key:
{
"app_secret": "<MY_SECRET_KEY>"
}
I'm already using a package in my app to handle .env files: https://github.com/luggit/react-native-config
Is there any way to use this package or another one, in order to get the APP_SECRET for the appcenter config files from a ENV variable?
I just don't want to keep these keys under version control.
Appcenter allows us to use build scripts, you can see more details here:
https://learn.microsoft.com/en-us/appcenter/build/custom/scripts
The workaround I found to fix this was using a post-clone script. You need to create a bash script on the root folder of your app that will write the .env file using the environment variables.
First, create a new file called appcenter-post-clone.sh.
And after you can write your .env file with something like this:
#!/usr/bin/env bash
echo "Creating .env file"
cat > ./.env <<EOL
API_URL=${API_URL}
API_KEY=${API_KEY}
EOL
Found this - The app secret (name is a bit confusing) is only for checking in-app updates - its seems you cannot trigger release with it.
So I think it is unnecessary to move the secret to the .env file.

Vue-cli 3 Environment Variables all undefined

I've tried all of the solutions out there but none seem to work for me. I just want to store some values in a .env file within my Vue app but simply trying to log process.env returns an empty object from within the component.
My .env file
VUE_APP_URL={api url}
VUE_APP_TOKEN={token}
My plan was to set these environment variables to data properties but it always returns undefined. If I do console.log(process.env.NODE_ENV) from webpack.config.js it will show that I'm in development but if I tried doing the same from within the component like
mounted() {
this.$nextTick(() => {
console.log(process.env.VUE_APP_URL);
})
}
It just returns undefined.
A few tips for people who land here:
Make sure your .env files are in the project root folder (and not in say src/)
Variable names should start with VUE_APP_ if to be statically embedded into the client bundle
Restart the dev server or build your project for changes to take effect
If you are migrating from a webpack based solution make sure that you replace : (from JSON config) with = (dotenv format). Easy to miss
Make sure you've saved any changes to your .env files.
In old Vue versions environment variables were defined in e.g. config/dev.env.js instead of the .env files in root
I figured it out - I had to install dotenv-webpack and initialize it in webpack.config.js which is odd because none of the docs stated that I needed to do so.
Install dotenv-webpack and configure the vue.config.js file as follows.
npm install dotenv-webpack --save-dev
Add this to your config file:
const Dotenv = require('dotenv-webpack');
module.exports = {
configureWebpack: {
plugins: [
new Dotenv()
]
}
}
In your .env file make sure you add VUE_APP_ before your variables like this:
VUE_APP_VAR1=example
VUE_APP_VAR2=value
Now you can access these variables in your Vue application:
console.log(process.env.VUE_APP_VAR1); // "example"
console.log(process.env.VUE_APP_VAR2); // "value"
Here some links for reference:
https://www.npmjs.com/package/dotenv-webpack
https://cli.vuejs.org/guide/webpack.html
https://cli.vuejs.org/guide/mode-and-env.html#environment-variables
so I use
VUE_APP_API_URL (this doesn't work)
then I change it to
VUE_APP_APIURL (this works)
hope it helps
If your vue-cli version is higher than 3.x and you put your .env files in root directory like said in comments. Than you can access your environmental variables from components (like this process.env.VUE_APP_YOUR_VARIABLE).
As said in vue-cli docs
Only variables that start with VUE_APP_ will be statically embedded into the client bundle with webpack.DefinePlugin. You can access
them in your application code: console.log(process.env.VUE_APP_SECRET)
I put my .env file in the root directory and appended each variable with VUE_APP_.
To demonstrate this, for example, if the variable you want to use is API_BASE_URL
In your .env file, you put the variable as VUE_APP_API_BASE_URL=baseurl/api/v1
To access it in your files, you do process.env.VUE_APP_API_BASE_URL.
CAVEAT:
Never put any sensitive information you don't want anybody to see, on your front-end. The most common thing you won't want anybody to see (as regards web development) is your API Key. There are real consequences to doing this. This is one such example of someone who has been burned exposing API keys to the public.
However, even if you put your sensitive data in a .env file and add the .env file to a .gitignore file (hence not pushing it to a Git repository hosting service e.g Github, BitBucket, Gitlab etc.), your data is still not safe on the front-end. It's only safe when this is done on back-end code as it will be hosted on a server.
In the front-end, anyone who is determined enough can find your sensitive information. All your information is available on a browser and all that person needs to do is to open the dev tools and check the Sources tab, and BOOM all your sensitive information is laid bare.
Environment variables on the front-end are only useful when you want one reference point for NON-SENSITIVE information, such as a BASE URL, as seen in the example above. A BASE URL can change during the course of development and you won't want to change all references in the application folder manually. It is tedious plus you may miss a few, which would lead to errors.
If you want to avoid exposing your API keys and other sensitive information you may require on the front-end, take a look at this article.
This is what worked for me. I previously created my .env.development and .env.production files in the root folder by manually by right-clicking in the Exploer in VS Code and adding a new file. This kept giving me undefined.
I deleted the files and first installed npm install touch-cli -g
Once installed, i added the environment files as such touch .env.production and touch .env.productionand itworks. So I think there's a difference between how these env files are generated.
NOTE: I do not have webpack installed. Just using the vue cli to build
VS Code ExplorerChrome Developer Tools
IF you are using VITE, use VITE_ in stead of VUE_APP
Vue CLI dotenv usage suffers the inability to provide the .env variables other than prefixed with VUE_APP_. This is OK but this is far not enough to satisfy any even little serious web project that wants to conveniently and securely manage its (sometimes huge) list of variables for different environments.
Here is the solution that makes use of .env variables as convenient as on backends with dotenv.
With this solution you could access your MY_EXTERNAL_API_KEY from your .env[.environment] file in your code like this const key = process.env.MY_EXTERNAL_API_KEY.
It provides:
The convenience of using non-prefixed with VUE_APP_ variables' names and use .env variable expansion feature (use ${VARNAME} kind of variables)
The necessary security: your variables are neither available at browser console with console.log(pocess.env.MYVAR) at run time nor are explorable via text search by their names from .env files within the built application's JS bundle.
You can still use original Vue CLI solution along;
For this use dotenv-webpack plugin in your vue.config.js as follows:
const Dotenv = require('dotenv-webpack');
const envPath = function() {
return (!process.env.NODE_ENV || (process.env.NODE_ENV === 'development')) ?
'./.env' :
`./.env.${process.env.NODE_ENV}`;
}
const dotenvArgs = {
expand: true,
path: envPath()
};
module.exports = {
//... some other config here
configureWebpack: {
plugins: [
new Dotenv(dotenvArgs)
]
}
};
Here:
expand: true allows for ${MYVAR} variables expansion;
path: envPath() allows to define custom .env file name depending on your Vue CLI project environments, and the path depending on you project structure;
There are other useful dotenv-webpack options you could use.
I believe this solution is good enough to fully satisfy most frequent use cases.
NB: Remember as you pass your secret variables set via .env into HTTP requests from your front-end (e.g. an API key in a call to some external API) they are visible to any one who knows where to look. To diminish security risks for this situation there are different solutions.
Just to hint you have either to:
provide only publicly open data via your application;
or authenticate your application (or parts of it) via some authentication service (login/password + JWT|sessions, external authentication providers e.g. Facebook, Google etc.);
or resort to server-generated application.
But this is the whole separate subject.
if you are cominng from VUE-cli-2 or you just cloned/installed an old vuejs project and you can't find .env file, this article explains what you have to do to set your .env variables as they environment files are probably located in config/dev.env.js (Note: this is peculiar to Vue-cli-2 files)
Here is also a solution and a detailed explanation for Vue-cli-3 .env related issue
What worked for me was changing from .env to .env.local. Haven't investigated WHY but I checked an old project and saw that I had a .env.local instead and did same for this project that would not pick the values from .env irrespective of whether vars where prefixed with VUE_APP and it worked.
It seems environment variables are not accessible in child Vue components. Best to declare them globally in main.js with Vue.prototype.env = process.env;
I know that this question was asked about vue-cli 3, which generates code for Vue 2. But it is the top result if you google for "vue3 does not embed env" and similar queries, so I assume that a lot of people end up here when having trouble with process.env variables being undefined in their Vue 3 app.
So this is an answer about how to fix your Vue 3 env issues.
This is what causes the confusion
If you google for env problems with vue, you end up in the vue-cli docs. But vue-cli was replaced by create-vue in Vue 3. There is a alert box at the top of the page that tells you this, but you've probably missed it.
If you did not miss it and followed one of the two links in the box, you ended up in the Vue 3 tooling guide or in the create-vue repo. None of those resources mention env variables. But you learn that create-vue is based on Vite.
If you follow that lead and google for "vite env", you end up in the vite documentation, where you finally find the answer:
env variables have to be prefixed with VITE_ to be compiled into the app (as opposed to VUE_APP_ in vue 2)
env variables will be available in import.meta.env in your app (as opposed to process.env in vue 2)
The latter one is what took me the longest to figure out.
This is how you need to do it
in an .env file in your project root:
VITE_MY_ENV_VAR=foo
The docs will also tell you about the different naming patterns for .env files in Vite. Very useful information if you work with different environments!
in your app:
const my_env_var = import.meta.env.VITE_MY_ENV_VAR
I hope this saves someone the time for figuring this out.
It might also help: make sure your .env files are in lowercase letters because in Linux it won't work even if it is working in windows
The answer provided here helped me out. I'm using Laravel with an odd setup for Vue 2.x. The project is also using Laravel Mix. Here's the solution:
Inside of your .env file, which is a sibling of package.json:
MY_ENVIRONMENT_VARIABLE=my_value
Inside of webpack.mix.js:
const { mix } = require('laravel-mix');
mix.webpackConfig(webpack => {
return {
plugins: [
new webpack.EnvironmentPlugin (
['MY_ENVIRONMENT_VARIABLE']
)
]
};
});
Afterwards, an npm run dev or npx mix should allow you to use these variables.
Credit: Thorsten Lünborg

How to use config variable in React Native

I am new in react-native and haven't use any starter kit.
my question is how can I use config variables. say for example i have api url which is diffrent for production and development. I don't want to go in each page change url every time.
That's why i want to use something like config variables.
any suggestions ?
pretty simple question.. you can use react-native-config. Follow the steps:
npm install react-native-config --save
react-native link react-native-config
Create a new file .env in the root of your React Native app:
API_URL_LIVE=https://myapilive.com
API_URL_DEV=https://myapidev.com
Then access variables defined there from your app:
import Config from 'react-native-config'
Config.API_URL_LIVE // 'https://myapilive.com'
Note: Don't forget to clean you build after changing the URLs. Use following command.
cd android
gradlew clean build

Change code push deployment key React native

While integrating code-push in my react-native app using code-push tutorial, i ran following command:
react-native link react-native-code-push
It asked for deployment keys then, which i pasted but now i want to change those keys.
I tried to unlink with the following command but its not working,
react-native unlink react-native-code-push
Can someone please guid me, as i'm new to both react-native and code push?
For IOS:
file:
list.info
key:
CodePushDeploymentKey
For Android:
file:
strings.xml
key:
reactNativeCodePush_androidDeploymentKey
update values of these keys and it will work :)
So basically deployment keys can be stored in different locations and it depends upon how you have configured the application.
You can always find what is the location of the deployment key the following way:
1) For Android it is injected in MainApplication.java file -> getPackages method (the 1st parameter for CodePush class constructor).
By default it should be R.string.reactNativeCodePush_androidDeploymentKey which points exactly to strings.xml file. You can override this if needed and store deployment key in arbitrary place or simply hard-code it here (though it is not recommended).
2) For iOS the default place to store deployment key is Info.plist file located in iOS folder of the application (entry named CodePushDeploymentKey).
Later it is extracted by the app in native module in CodePushConfig.m class.