Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment variables don't seem to be detected in build #2195

Open
JorensM opened this issue Jan 22, 2024 · 59 comments
Open

Environment variables don't seem to be detected in build #2195

JorensM opened this issue Jan 22, 2024 · 59 comments
Labels
needs review Issue is ready to be reviewed by a maintainer

Comments

@JorensM
Copy link

JorensM commented Jan 22, 2024

Build/Submit details page URL

https://expo.dev/accounts/jorensm/projects/app/builds/3dcb9d5c-dfb2-487d-a6e5-8ce5c65b2288

Summary

So I'm trying to add environment variables to my EAS build. I've added them in my eas.json file, like so:

env vars

But they don't seem to be detected in my build. I have a validator function that throws an error if the env variables are not set, and its throwing it in my builds, thought it works fine with Expo Go.

Managed or bare?

Managed

Environment

expo-env-info 1.2.0 environment info:
System:
OS: Windows 10 10.0.19045
Binaries:
Node: 20.8.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.17 - ~\AppData\Roaming\npm\yarn.CMD
npm: 10.1.0 - C:\Program Files\nodejs\npm.CMD
SDKs:
Android SDK:
API Levels: 30, 31, 33
Build Tools: 30.0.2, 30.0.3
IDEs:
Android Studio: Version 2020.3.0.0 AI-203.7717.56.2031.7678000
npmPackages:
@expo/webpack-config: ^19.0.0 => 19.0.0
expo: ~49.0.15 => 49.0.21
expo-router: ^2.0.0 => 2.0.14
react: 18.2.0 => 18.2.0
react-dom: 18.2.0 => 18.2.0
react-native: 0.72.6 => 0.72.6
react-native-web: ~0.19.6 => 0.19.10
Expo Workflow: managed

expo-doctor didn't find any issues

Error output

No response

Reproducible demo or steps to reproduce from a blank project

This is the file that loads my env variables. On Expo Go it doesn't throw an error but on a EAS build it does.

// Constants from environment variables

const ENV_VARIABLE_NAMES = [
    'API_URL',
    'STRIPE_PUBLISHABLE_KEY',
    'SUPABASE_URL',
    'SUPABASE_KEY'
]

const validateEnvVariables = () => {
    const missing_vars = []
    for(const var_name of ENV_VARIABLE_NAMES) {
        const full_var_name = 'EXPO_PUBLIC_' + var_name
        if(!process.env[full_var_name]) {
            missing_vars.push(full_var_name)
        }
    }

    if (missing_vars.length > 0) {
        throw new Error('Missing the following environment variables: ' + missing_vars.join(', '))
    }
}

validateEnvVariables();

export const API_URL = process.env.EXPO_PUBLIC_API_URL!;
export const SUPABASE_URL = process.env.EXPO_PUBLIC_SUPABASE_URL!;
export const SUPABASE_KEY = process.env.EXPO_PUBLIC_SUPABASE_KEY!;
export const STRIPE_PUBLISHABLE_KEY = process.env.EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY!;
@JorensM JorensM added the needs review Issue is ready to be reviewed by a maintainer label Jan 22, 2024
@JorensM
Copy link
Author

JorensM commented Jan 22, 2024

Apparently Expo only supports dot notation for accessing env variables. Which is strange because it worked with Expo Go. I'll try changing the validator to use dot notation and report back.

@JorensM
Copy link
Author

JorensM commented Jan 22, 2024

Update: After changing my validator to use dot notation, I'm still getting the same error about missing env vars

@JorensM
Copy link
Author

JorensM commented Jan 22, 2024

When I run the build command it does show in the CLI that the env variables were added:

console output

Whereas in my EAS build logs, under Spin up build envrionment it doesn't show the env variables (though I'm not sure if it should)

@szdziedzic
Copy link
Member

Hi there,

I wanted to check your build logs, but they are expired. Are you still facing this issue? If so may I ask you to run the build once again and send me the link?

@JorensM
Copy link
Author

JorensM commented Feb 6, 2024

@szdziedzic I'm not working on this project anymore as my client decided to pivot, but I'll try to re run the build when I have some free time

@i-mighty
Copy link

Can confirm this a real issue I am facing.

@ermamud
Copy link

ermamud commented Feb 25, 2024

I am having the same issue as well

@EmilChigu
Copy link

Also having the same issue except i can actually see them in the spin up build environment step. However when i publish my app, they are not there.

Screenshot 2024-03-01 at 09 36 06

@pariah140
Copy link

Hello was this solved. I have the same issue. It works fine in expo go but when I run a dev build they are all undefined.

@Inalegwu
Copy link

Has anyone found a solution to this issue yet ?

@anup-a
Copy link

anup-a commented Mar 28, 2024

I had a similar issue, while doing local eas build. Everything looks to be working well with expo builds, but fails during eas local builds.

It appears that I needed to set the environment variables for the execution of build command. So, here is what I did -

  1. created a bash script set-env.sh (It reads your .env file, and sets the environment)
#!/bin/bash

if [ $# -lt 1 ]; then
  echo "Usage: $0 <command>"
  exit 1
fi

(env $(cat .env | xargs) "$@")

  1. Run - sh set-env.sh eas build --profile test --platform ios --local

@ihaddy
Copy link

ihaddy commented May 24, 2024

this is still an issue, the above script by @anup-a doesn't work for me.

have a .env file and also a eas.json file

 "build": {
    "development": {
      "developmentClient": true,
      "env": {
        "EXPO_PUBLIC_BASE_URL": "....."}
       }
    }

still not working. kind of a big deal breaker and show stopper for running local builds where you can't leverage EAS cloud builds due to enterprise compliance reasons?

trying to call this in app code

  const response = await axios({
        method: method,
        url: `${process.env.EXPO_PUBLIC_BASE_URL || process.env.BASE_URL || 'did not load'}${url}`,
        data: body,
        headers: {
          'Content-Type': 'application/json',
          'securetoken': process.env.EXPO_PUBLIC_SECURE_TOKEN || process.env.SECURE_TOKEN || 'did not load' ,
          'Authorization': jwtToken ? `Bearer ${jwtToken}` : '',
          ...headers
        }
      });

i get 'did not load' in the development and production apk builds of the app ONLY, in expo go and the web browser it loads.

any advice?

@jonra1993
Copy link

jonra1993 commented May 30, 2024

I have the same issue the environment variables appear in the expo logs console. But when I publish to play store the build of the app crashes because it says that the environment variable does not exist EXPO_PUBLIC_SUPABASE_URL. I works in development mode.

image
  expo-env-info 1.2.0 environment info:
    System:
      OS: macOS 13.6.7
      Shell: 5.9 - /bin/zsh
    Binaries:
      Node: 20.11.1 - ~/.nvm/versions/node/v20.11.1/bin/node
      Yarn: 4.2.2 - ~/.nvm/versions/node/v20.11.1/bin/yarn
      npm: 10.2.4 - ~/.nvm/versions/node/v20.11.1/bin/npm
      Watchman: 2024.01.22.00 - /usr/local/bin/watchman
    Managers:
      CocoaPods: 1.15.2 - /Users/jona/.rvm/gems/ruby-3.3.0/bin/pod
    SDKs:
      iOS SDK:
        Platforms: DriverKit 23.2, iOS 17.2, macOS 14.2, tvOS 17.2, visionOS 1.0, watchOS 10.2
    IDEs:
      Android Studio: 2023.2 AI-232.10300.40.2321.11567975
      Xcode: 15.2/15C500b - /usr/bin/xcodebuild
    npmPackages:
      expo: ~51.0.9 => 51.0.9 
      expo-router: ~3.5.14 => 3.5.14 
      react: 18.2.0 => 18.2.0 
      react-native: 0.74.1 => 0.74.1 
      react-native-web: ^0.19.11 => 0.19.11 
    npmGlobalPackages:
      eas-cli: 9.1.0
      expo-cli: 6.3.10
    Expo Workflow: bare

@KristianLentino99
Copy link

I have the same issue here

@sthay8f
Copy link

sthay8f commented Jun 10, 2024

I have the same issue today.

The environment variable is correct when Spin up build environment in Logs.

圖片

圖片

@dawidvdh
Copy link

Yeah this is really problematic for me also, on production builds the env vars just are not present.

@varofon
Copy link

varofon commented Jun 11, 2024

Similar-ish issue here.
npx expo run:android works fine and loads all EXPO_PUBLIC_ env variables from .env
But npx expo run:android --variant release says that it loads variables in log, but process.env only has NODE_ENV in it

@hkhawar21
Copy link

Facing a similar issue
Env variables are loaded when running the application in development client mode or with expo go but no env variables are loaded with npx expo start --no-dev --minify

@dawidvdh
Copy link

dawidvdh commented Jun 17, 2024

Yeah this is really problematic for me also, on production builds the env vars just are not present.

In the end this was me missing a vital piece of documentation on the standard env resolution I had a .env.ci which although is not listed there seems to have taken preference over .env and so it appeared empty but in actual fact those values in the .env.ci file did not exist.

Weird gotcha, but I resolved this by combining the CI and app envs into a single .env.

@Anis-Ghliss
Copy link

I am facing the same issue, although the env variable is detected in dev mode, it is not when I run eas build, even though the logs show that it is loaded

@saifborghol
Copy link

You need to add EXPO_PUBLIC_ befor each variable
Folow this example
Capture d'écran 2024-06-26 232758
https://docs.expo.dev/guides/environment-variables/#migrating-to-expo-environment-variables

@cameronmurphy
Copy link

This is annoying. local-build-plugin does not copy any .env files into the build dir when doing an EAS build locally. Currently the only way to get environment variables into the build is to manually export them before running eas build as per @anup-a's answer.

@yogendra-meta
Copy link

I even manually exported them, still facing the issue, no env vars were being read

@magix022
Copy link

Having the same issue here, I can see the variable in the eas spin-up build environment too but its not there in the app.

@rafaelgrilli92
Copy link

I'm having the exact same issue! I can't make the production build app work because the ENV are not present anymore. It all started after updating from Expo 49 to 50!!! This is ridiculous!

@samimenouar
Copy link

Well, that's weird. If I have console.error(process.env); before using the environement variables, everything works (even in Release mode). But as soon as I take it out, the variable is not available and the app crashes...

@rafaelgrilli92
Copy link

rafaelgrilli92 commented Jul 19, 2024

Well, that's weird. If I have console.error(process.env); before using the environement variables, everything works (even in Release mode). But as soon as I take it out, the variable is not available and the app crashes...

@samimenouar , That's very strange! Have you built the apk and the env variables work after you console.log the process.env?

@dragospeta
Copy link

I managed to find a solution. (Was pretty scared to see an opened issue from January)

I added my env in eas.json, ex:

"preview": {
    "distribution": "internal",
    "node": "18.18.2",
    "yarn": "1.22.19",
    "env": {
        "EXPO_PUBLIC_API_URL": "https://www.some_url.com/api",
    }
}

I wrote in app.config.js (if you don't have it it's app.json and you have to rename it):

export default {
    expo: {
        name: "your app name",
        ....other config stuff
        extra: {
            ...
            EXPO_PUBLIC_API_URL: process.env.EXPO_PUBLIC_API_URL
        }
 }

Then i have a file named model.tsx and i used the expo-constants library (yarn add expo-constants, or npm install):

import Constants from "expo-constants";

const extra = Constants.expoConfig?.extra;

const API_URL = extra?.EXPO_PUBLIC_API_URL ?? "";

export { API_URL }

Now everywhere i import import { API_URL } from "./model"; it has the right value.

@kaushiksahoo2000
Copy link

Can confirm the above works as well. Similar solution referenced in the Expo discord here

@brandtnewlabs
Copy link

Same issue here. Took me a day to realise the EXPO_PUBLIC_… variables are undefined in production. App crashed on startup, as Supabase didn't get the right URL.

@rafaelgrilli92
Copy link

This is a major issue and there's still no answer for it. I'm currently on the "on-demand" plan in EXPO Dev, which means I pay $1 every time I do a build, and before I realised that this was an issue with EXPO, and not my code, I did at least 5 builds + the time and effort wasted on trying to find an issue that is not even in my application. We need this fixed ASAP!!!

@SwhiteMHC
Copy link

I am also experiencing this issue. When values are defined in my .env file as EXPO_PUBLIC_VAR, and in my eas.json, when running locally none of the variables appear.

@zollipaul
Copy link

zollipaul commented Aug 20, 2024

For me, the script below successfully makes the environment variables available for eas build, since it directly sources the .env file in the current shell context. This is more reliable and ensures that all environment variables are properly loaded and available for the eas build command

set-env.sh:

#!/bin/bash

# Load environment variables
set -a; source .env; set +a

# Execute command passed as arguments to this script
"$@"

run it like this:
./set-env.sh eas build --profile preview:device --platform ios --local

@Ception
Copy link

Ception commented Aug 25, 2024

router

You. Are. A. Godsend.
After 4 hours of beating my head against the wall and trying everything under the sun, including reading dozens of doc files, and tons of stackoverflow. This was the only solution that worked.

I can confirm this actually worked. Just a small correction to this:

I wrote in app.config.js (if you don't have it it's app.json and you have to rename it):

You do not need to rename your app.json to app.config.js, I'm sure they both work the same, but you can keep your existing app.json and add on EXPO_SECRET_KEY to extra in app.json and it works just the same.

Thank youuuuuu!!!!

@ppinel
Copy link

ppinel commented Aug 26, 2024

Same issue for me and it took me a while to figure it out. iOS doesn't say anything, and crash report is useless.
I'll use the workaround waiting for an official solution (?)

Thanks guys !

@djMax
Copy link

djMax commented Aug 27, 2024

I still don't understand what's at play here. This is basically eas-cli's whole job, and it USED to work. Latest versions 11.x break environment variable resolution.

@kutsan
Copy link

kutsan commented Aug 28, 2024

In addition to expo-constants instructions above, my approach was to use the dotenv-cli package. This tool loads environment variables into the current shell context. You can create a script in package.json to use with eas-cli. I think this is as clean as it gets.

npm i dotenv-cli -D

For .env.development file, you can use:

"build:android": "dotenv -c development -- eas build --platform android --profile preview --local",

Package docs: https://www.npmjs.com/package/dotenv-cli

@Cancuuu
Copy link

Cancuuu commented Aug 29, 2024

I waste time and money with this issue, please fix it ASAP! Im willing to help if you need it @Expoteam

@mjko2000
Copy link

Did you guys try to change to

presets: ['babel-preset-expo']

in babel.config.js ?

@sanchit-bhalla
Copy link

This fix works for me but there might be a better way to fix it. Basically what I have observed is that when the .env file is gitignored then environment variables are not loaded. So before generating the build we need to remove it from the .gitignore file.

  1. Before running the build command, remove .env from the .gitignore file and save the .gitignore file.
  2. Then run the build command eas build --platform android --profile preview
  3. After the build is generated, add .env back to .gitignore file

I only have .env file and didn't add env property in the eas.json

@Cancuuu
Copy link

Cancuuu commented Sep 6, 2024

This fix works for me but there might be a better way to fix it. Basically what I have observed is that when the .env file is gitignored then environment variables are not loaded. So before generating the build we need to remove it from the .gitignore file.

  1. Before running the build command, remove .env from the .gitignore file and save the .gitignore file.
  2. Then run the build command eas build --platform android --profile preview
  3. After the build is generated, add .env back to .gitignore file

I only have .env file and didn't add env property in the eas.json

Thats an interest solution, do you think that is the same for local build (with --local flag)??
this command for example 👉 eas build --platform android --local

@sanchit-bhalla
Copy link

I haven't tried building locally yet but if you are facing the issue because the environment variables are not loaded properly, you can try this way.

@lgustavosoftwareengineer
Copy link

lgustavosoftwareengineer commented Sep 11, 2024

I managed to find a solution. (Was pretty scared to see an opened issue from January)

I added my env in eas.json, ex:

"preview": {
    "distribution": "internal",
    "node": "18.18.2",
    "yarn": "1.22.19",
    "env": {
        "EXPO_PUBLIC_API_URL": "https://www.some_url.com/api",
    }
}

I wrote in app.config.js (if you don't have it it's app.json and you have to rename it):

export default {
    expo: {
        name: "your app name",
        ....other config stuff
        extra: {
            ...
            EXPO_PUBLIC_API_URL: process.env.EXPO_PUBLIC_API_URL
        }
 }

Then i have a file named model.tsx and i used the expo-constants library (yarn add expo-constants, or npm install):

import Constants from "expo-constants";

const extra = Constants.expoConfig?.extra;

const API_URL = extra?.EXPO_PUBLIC_API_URL ?? "";

export { API_URL }

Now everywhere i import import { API_URL } from "./model"; it has the right value.

Works for me in combination with: #2195 (comment) solution

@Ception
Copy link

Ception commented Sep 11, 2024

Solution for Using Environment Variables in Expo with EAS Build

After diving deep into Expo's documentation and blogs, I’ve finally figured out how to properly handle environment variables in Expo projects, especially with EAS builds. I’m sharing this to help others who might run into the same issues.

First, I recommend reviewing the following:

  1. Environment Variables in Expo
  2. Environment Variables and Secrets in EAS Build

How it Works

  • app.json: Defines project details for Expo, such as:

    • App name
    • Version
    • Plugins
    • Platform-specific configurations (ios, android)
  • eas.json: Instructs the EAS service on how to handle the build process based on the project’s configuration.

Step-by-Step Guide

  1. Create a .env file in your project root and prefix your variables with EXPO_PUBLIC_. For example:

    EXPO_PUBLIC_SUPABASE_ANON_KEY="eyJ..."
  2. To access these variables in your project, use:

    const myVariable = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY;
    console.log(`Proof that this loads: ${myVariable}`);
  3. For better accessibility, you can create a config.ts file:

    const config = {
      SUPABASE_URL: process.env.EXPO_PUBLIC_SUPABASE_URL ?? "",
      SUPABASE_KEY: process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY ?? "",
    };
    
    export default config;

Important Note:

.env files are not included in your EAS build by default.

Using Environment Variables in EAS Builds

If you want to use your local environment variables during EAS builds:

  1. Create the same variables in your Expo project’s secrets. You can find them here:
    https://expo.dev/accounts/<username>/settings/secrets

  2. Update your eas.json to tell EAS which secrets to use for specific branches (e.g., development, production):

    "development": {
      "autoIncrement": true,
      "developmentClient": true,
      "distribution": "internal",
      "env": {
        "EXPO_PUBLIC_SUPABASE_URL": "EXPO_PUBLIC_SUPABASE_URL",
        "EXPO_PUBLIC_SUPABASE_ANON_KEY": "EXPO_PUBLIC_SUPABASE_ANON_KEY"
      },
      "channel": "development"
    }

This tells EAS to look for EXPO_PUBLIC_SUPABASE_ANON_KEY in the secrets and retrieve its value during the build.

Pushing Secrets Directly from the Command Line

To avoid manually setting up secrets in the Expo dashboard, you can push your .env file directly:

eas secret:push --scope project --env-file .env

This will automatically upload your existing env to project specific secrets.

I hope this helps someone else in the future because dealing with this was a total nightmare! But now that I understand the flow of Expo’s configurations, it’s much clearer!

PS: If you have anything to add, or if you think I might’ve misunderstood something, I’m all ears.

A Few Key Notes:

  • Using the --local flag will still use EAS Services, but make the build locally on your computer, instead of the cloud, meaning you’ll still need to update EAS Secrets / JSON
  • You do not need to remove your .env from your .gitignore.
  • No need to add any configurations or environment variables to app.config.js or app.json.

@marinoandrea
Copy link

marinoandrea commented Sep 16, 2024

It looks like the use of EXPO_PUBLIC* env vars has some drawbacks. The docs do discuss how to centralize configuration variables based on channels (and prevent EAS Updates from overriding the vars set by EAS Build which is what I believe is happening to most people here, me included).

@fellenabmb
Copy link

I managed to find a solution. (Was pretty scared to see an opened issue from January)

I added my env in eas.json, ex:

"preview": {
    "distribution": "internal",
    "node": "18.18.2",
    "yarn": "1.22.19",
    "env": {
        "EXPO_PUBLIC_API_URL": "https://www.some_url.com/api",
    }
}

I wrote in app.config.js (if you don't have it it's app.json and you have to rename it):

export default {
    expo: {
        name: "your app name",
        ....other config stuff
        extra: {
            ...
            EXPO_PUBLIC_API_URL: process.env.EXPO_PUBLIC_API_URL
        }
 }

Then i have a file named model.tsx and i used the expo-constants library (yarn add expo-constants, or npm install):

import Constants from "expo-constants";

const extra = Constants.expoConfig?.extra;

const API_URL = extra?.EXPO_PUBLIC_API_URL ?? "";

export { API_URL }

Now everywhere i import import { API_URL } from "./model"; it has the right value.

This did work for me, I can now access env variables in both development an eas builds.
Generally, i wouldn't complain when something is not working in an open source project. But in this case, the company where I work is paying per build in EAS, and having to do a workaround for this is honestly not good. I'd expect something as common and basic as environment handling to work properly when using a paid service.

@tbanj
Copy link

tbanj commented Sep 24, 2024

Solution for Using Environment Variables in Expo with EAS Build

After diving deep into Expo's documentation and blogs, I’ve finally figured out how to properly handle environment variables in Expo projects, especially with EAS builds. I’m sharing this to help others who might run into the same issues.

First, I recommend reviewing the following:

1. [Environment Variables in Expo](https://docs.expo.dev/guides/environment-variables/)

2. [Environment Variables and Secrets in EAS Build](https://docs.expo.dev/build-reference/variables/)

How it Works

* **`app.json`**: Defines project details for Expo, such as:
  
  * App name
  * Version
  * Plugins
  * Platform-specific configurations (`ios`, `android`)

* **`eas.json`**: Instructs the EAS service on how to handle the build process based on the project’s configuration.

Step-by-Step Guide

1. **Create a `.env` file in your project root** and prefix your variables with `EXPO_PUBLIC_`. For example:
   ```shell
   EXPO_PUBLIC_SUPABASE_ANON_KEY="eyJ..."
   ```

2. To access these variables in your project, use:
   ```js
   const myVariable = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY;
   console.log(`Proof that this loads: ${myVariable}`);
   ```

3. For better accessibility, you can create a `config.ts` file:
   ```ts
   const config = {
     SUPABASE_URL: process.env.EXPO_PUBLIC_SUPABASE_URL ?? "",
     SUPABASE_KEY: process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY ?? "",
   };
   
   export default config;
   ```

Important Note:

.env files are not included in your EAS build by default.

Using Environment Variables in EAS Builds

If you want to use your local environment variables during EAS builds:

1. **Create the same variables** in your Expo project’s secrets. You can find them here:
   `https://expo.dev/accounts/<username>/settings/secrets`

2. **Update your `eas.json`** to tell EAS which secrets to use for specific branches (e.g., `development`, `production`):
   ```json
   "development": {
     "autoIncrement": true,
     "developmentClient": true,
     "distribution": "internal",
     "env": {
       "EXPO_PUBLIC_SUPABASE_URL": "EXPO_PUBLIC_SUPABASE_URL",
       "EXPO_PUBLIC_SUPABASE_ANON_KEY": "EXPO_PUBLIC_SUPABASE_ANON_KEY"
     },
     "channel": "development"
   }
   ```

This tells EAS to look for EXPO_PUBLIC_SUPABASE_ANON_KEY in the secrets and retrieve its value during the build.

Pushing Secrets Directly from the Command Line

To avoid manually setting up secrets in the Expo dashboard, you can push your .env file directly:

eas secret:push --scope project --env-file .env

This will automatically upload your existing env to project specific secrets.

I hope this helps someone else in the future because dealing with this was a total nightmare! But now that I understand the flow of Expo’s configurations, it’s much clearer!

PS: If you have anything to add, or if you think I might’ve misunderstood something, I’m all ears.

A Few Key Notes:

* Using the `--local` flag will still use EAS Services, but make the build locally on your computer, instead of the cloud, meaning you’ll still need to update EAS Secrets / JSON

* You **do not** need to remove your `.env` from your `.gitignore`.

* No need to add any configurations or environment variables to `app.config.js` or `app.json`.

This your solution works for me

@chinnawat1995
Copy link

Solution from @Ception works for me.

@checkerap
Copy link

Solution for Using Environment Variables in Expo with EAS Build

After diving deep into Expo's documentation and blogs, I’ve finally figured out how to properly handle environment variables in Expo projects, especially with EAS builds. I’m sharing this to help others who might run into the same issues.

First, I recommend reviewing the following:

  1. Environment Variables in Expo
  2. Environment Variables and Secrets in EAS Build

How it Works

  • app.json: Defines project details for Expo, such as:

    • App name
    • Version
    • Plugins
    • Platform-specific configurations (ios, android)
  • eas.json: Instructs the EAS service on how to handle the build process based on the project’s configuration.

Step-by-Step Guide

  1. Create a .env file in your project root and prefix your variables with EXPO_PUBLIC_. For example:
    EXPO_PUBLIC_SUPABASE_ANON_KEY="eyJ..."
  2. To access these variables in your project, use:
    const myVariable = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY;
    console.log(`Proof that this loads: ${myVariable}`);
  3. For better accessibility, you can create a config.ts file:
    const config = {
      SUPABASE_URL: process.env.EXPO_PUBLIC_SUPABASE_URL ?? "",
      SUPABASE_KEY: process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY ?? "",
    };
    
    export default config;

Important Note:

.env files are not included in your EAS build by default.

Using Environment Variables in EAS Builds

If you want to use your local environment variables during EAS builds:

  1. Create the same variables in your Expo project’s secrets. You can find them here:
    https://expo.dev/accounts/<username>/settings/secrets
  2. Update your eas.json to tell EAS which secrets to use for specific branches (e.g., development, production):
    "development": {
      "autoIncrement": true,
      "developmentClient": true,
      "distribution": "internal",
      "env": {
        "EXPO_PUBLIC_SUPABASE_URL": "EXPO_PUBLIC_SUPABASE_URL",
        "EXPO_PUBLIC_SUPABASE_ANON_KEY": "EXPO_PUBLIC_SUPABASE_ANON_KEY"
      },
      "channel": "development"
    }

This tells EAS to look for EXPO_PUBLIC_SUPABASE_ANON_KEY in the secrets and retrieve its value during the build.

Pushing Secrets Directly from the Command Line

To avoid manually setting up secrets in the Expo dashboard, you can push your .env file directly:

eas secret:push --scope project --env-file .env

This will automatically upload your existing env to project specific secrets.

I hope this helps someone else in the future because dealing with this was a total nightmare! But now that I understand the flow of Expo’s configurations, it’s much clearer!

PS: If you have anything to add, or if you think I might’ve misunderstood something, I’m all ears.

A Few Key Notes:

  • Using the --local flag will still use EAS Services, but make the build locally on your computer, instead of the cloud, meaning you’ll still need to update EAS Secrets / JSON
  • You do not need to remove your .env from your .gitignore.
  • No need to add any configurations or environment variables to app.config.js or app.json.

this works and it's clearer than the docs. thank you!

@fellenabmb
Copy link

This is still going on 😁

@gregoriocarranza
Copy link

Solution for Using Environment Variables in Expo with EAS Build

After diving deep into Expo's documentation and blogs, I’ve finally figured out how to properly handle environment variables in Expo projects, especially with EAS builds. I’m sharing this to help others who might run into the same issues.

First, I recommend reviewing the following:

  1. Environment Variables in Expo
  2. Environment Variables and Secrets in EAS Build

How it Works

  • app.json: Defines project details for Expo, such as:

    • App name
    • Version
    • Plugins
    • Platform-specific configurations (ios, android)
  • eas.json: Instructs the EAS service on how to handle the build process based on the project’s configuration.

Step-by-Step Guide

  1. Create a .env file in your project root and prefix your variables with EXPO_PUBLIC_. For example:
    EXPO_PUBLIC_SUPABASE_ANON_KEY="eyJ..."
  2. To access these variables in your project, use:
    const myVariable = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY;
    console.log(`Proof that this loads: ${myVariable}`);
  3. For better accessibility, you can create a config.ts file:
    const config = {
      SUPABASE_URL: process.env.EXPO_PUBLIC_SUPABASE_URL ?? "",
      SUPABASE_KEY: process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY ?? "",
    };
    
    export default config;

Important Note:

.env files are not included in your EAS build by default.

Using Environment Variables in EAS Builds

If you want to use your local environment variables during EAS builds:

  1. Create the same variables in your Expo project’s secrets. You can find them here:
    https://expo.dev/accounts/<username>/settings/secrets
  2. Update your eas.json to tell EAS which secrets to use for specific branches (e.g., development, production):
    "development": {
      "autoIncrement": true,
      "developmentClient": true,
      "distribution": "internal",
      "env": {
        "EXPO_PUBLIC_SUPABASE_URL": "EXPO_PUBLIC_SUPABASE_URL",
        "EXPO_PUBLIC_SUPABASE_ANON_KEY": "EXPO_PUBLIC_SUPABASE_ANON_KEY"
      },
      "channel": "development"
    }

This tells EAS to look for EXPO_PUBLIC_SUPABASE_ANON_KEY in the secrets and retrieve its value during the build.

Pushing Secrets Directly from the Command Line

To avoid manually setting up secrets in the Expo dashboard, you can push your .env file directly:

eas secret:push --scope project --env-file .env

This will automatically upload your existing env to project specific secrets.

I hope this helps someone else in the future because dealing with this was a total nightmare! But now that I understand the flow of Expo’s configurations, it’s much clearer!

PS: If you have anything to add, or if you think I might’ve misunderstood something, I’m all ears.

A Few Key Notes:

  • Using the --local flag will still use EAS Services, but make the build locally on your computer, instead of the cloud, meaning you’ll still need to update EAS Secrets / JSON
  • You do not need to remove your .env from your .gitignore.
  • No need to add any configurations or environment variables to app.config.js or app.json.

I saw this repost in a million other github forums and in redit but it doesnt work for me.

I have my env (in local ) that is EXPO_PUBLIC_API_URL, and in expo screts i have EXPO_PUBLIC_API_URL_DEVELOPMENT and EXPO_PUBLIC_API_URL_PRODUCTION.

when i access it with process.env.EXPO_PUBLIC_API_URL_DEVELOPMENT i dont have any problems (the build is using the expo secrets) buttt, when i try to use it in the eas.json like this

{
  "cli": {
    "version": ">= 10.2.1"
  },
  "build": {
    "development": {
      "developmentClient": false,
      "distribution": "internal",
      "env": {
        "EXPO_PUBLIC_NODE_ENV": "development",
        "EXPO_PUBLIC_API_URL": "EXPO_PUBLIC_API_URL_DEVELOPMENT",
        "EXPO_PUBLIC_GOOGLE_MAPS_API_KEY": "EXPO_PUBLIC_GOOGLE_MAPS_API_KEY"
      }
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {
      "env": {
        "EXPO_PUBLIC_NODE_ENV": "production",
        "EXPO_PUBLIC_API_URL": "EXPO_PUBLIC_API_URL_PRODUCTION",
        "EXPO_PUBLIC_GOOGLE_MAPS_API_KEY": "EXPO_PUBLIC_GOOGLE_MAPS_API_KEY"
      }
    }
  },
  "submit": {
    "production": {}
  }
}

it use the literal string "EXPO_PUBLIC_API_URL_DEVELOPMENT" or "EXPO_PUBLIC_API_URL_PRODUCTION".

im trying to use it in the eas for convenience but i will try the app.config.js option

@JorensM
Copy link
Author

JorensM commented Oct 31, 2024

Hi there,

I wanted to check your build logs, but they are expired. Are you still facing this issue? If so may I ask you to run the build once again and send me the link?

Hi, sorry for the late response. Here is my build log: https://expo.dev/accounts/jorensm/projects/app/builds/58dc3481-75ce-43b1-bffd-5c4b46499a62 (hopefully you can access it with this link)

And my eas.json:

{
  "cli": {
    "version": ">= 0.48.2",
    "appVersionSource": "remote"
  },
  "build": {
    "testing": {
      "distribution": "internal",
      "android": {
        "buildType": "app-bundle"
      },
      "env": {
        "EXPO_PUBLIC_API_URL": "XXX",
        "EXPO_PUBLIC_SUPABASE_URL": "XXX",
        "EXPO_PUBLIC_SUPABASE_KEY": "XXX",
        "EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY": "XXX"
      }
    },
    "preview": {
      "distribution": "internal",
      "android": {
        "buildType": "apk"
      },
      "env": {
        "EXPO_PUBLIC_API_URL": "XXX",
        "EXPO_PUBLIC_SUPABASE_URL": "XXX",
        "EXPO_PUBLIC_SUPABASE_KEY": "XXX",
        "EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY": "XXX"
      }
    },
    "production": {}
  },
  "submit": {
    "production": {}
  }
}

@JorensM
Copy link
Author

JorensM commented Oct 31, 2024

Solution for Using Environment Variables in Expo with EAS Build

After diving deep into Expo's documentation and blogs, I’ve finally figured out how to properly handle environment variables in Expo projects, especially with EAS builds. I’m sharing this to help others who might run into the same issues.

First, I recommend reviewing the following:

  1. Environment Variables in Expo
  2. Environment Variables and Secrets in EAS Build

How it Works

  • app.json: Defines project details for Expo, such as:

    • App name
    • Version
    • Plugins
    • Platform-specific configurations (ios, android)
  • eas.json: Instructs the EAS service on how to handle the build process based on the project’s configuration.

Step-by-Step Guide

  1. Create a .env file in your project root and prefix your variables with EXPO_PUBLIC_. For example:
    EXPO_PUBLIC_SUPABASE_ANON_KEY="eyJ..."
  2. To access these variables in your project, use:
    const myVariable = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY;
    console.log(`Proof that this loads: ${myVariable}`);
  3. For better accessibility, you can create a config.ts file:
    const config = {
      SUPABASE_URL: process.env.EXPO_PUBLIC_SUPABASE_URL ?? "",
      SUPABASE_KEY: process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY ?? "",
    };
    
    export default config;

Important Note:

.env files are not included in your EAS build by default.

Using Environment Variables in EAS Builds

If you want to use your local environment variables during EAS builds:

  1. Create the same variables in your Expo project’s secrets. You can find them here:
    https://expo.dev/accounts/<username>/settings/secrets
  2. Update your eas.json to tell EAS which secrets to use for specific branches (e.g., development, production):
    "development": {
      "autoIncrement": true,
      "developmentClient": true,
      "distribution": "internal",
      "env": {
        "EXPO_PUBLIC_SUPABASE_URL": "EXPO_PUBLIC_SUPABASE_URL",
        "EXPO_PUBLIC_SUPABASE_ANON_KEY": "EXPO_PUBLIC_SUPABASE_ANON_KEY"
      },
      "channel": "development"
    }

This tells EAS to look for EXPO_PUBLIC_SUPABASE_ANON_KEY in the secrets and retrieve its value during the build.

Pushing Secrets Directly from the Command Line

To avoid manually setting up secrets in the Expo dashboard, you can push your .env file directly:

eas secret:push --scope project --env-file .env

This will automatically upload your existing env to project specific secrets.

I hope this helps someone else in the future because dealing with this was a total nightmare! But now that I understand the flow of Expo’s configurations, it’s much clearer!

PS: If you have anything to add, or if you think I might’ve misunderstood something, I’m all ears.

A Few Key Notes:

  • Using the --local flag will still use EAS Services, but make the build locally on your computer, instead of the cloud, meaning you’ll still need to update EAS Secrets / JSON
  • You do not need to remove your .env from your .gitignore.
  • No need to add any configurations or environment variables to app.config.js or app.json.

Although this may work, I'm not sure if that's the expected behavior. I think that Secrets and Env Vars are different and have different uses.

From one of the pages you linked:

However, the recommended practice is to use .env files in your local environment, while defining environment variables for EAS Build in eas.json. Environment variables defined in your eas.json build profile will be used when evaluating your app.config.js when running eas build and will be available to all steps of the build process on the EAS Build server.

@GregBaLpro
Copy link

The "EAS secrets" doc page is unreachable it's pretty annoying :'(
https://docs.expo.dev/build-reference/variables/

@Zakisb
Copy link

Zakisb commented Nov 24, 2024

iNSANE NO ONE FROM THE EXPO AND EAS TEAM JOINED THE DISCUSSION AND PROVIDED A FIX ! WHAT ARE THEY DOING ?

@GaspardCLD
Copy link

GaspardCLD commented Dec 3, 2024

In my case, I tried many approaches and built a scenario for every possibility to access variables in my code (plain text, secret, declared directly in eas.json, added on the Expo website, with and without the EXPO_PUBLIC_ prefix).

What ultimately worked for me was the following setup:

  1. Keep the .env file as is and add it to .gitignore.
  2. Add the required environment variables on the Expo dashboard with plain text option, all with the EXPO_PUBLIC_ prefix.

Configure the environment in the Expo dashboard for each build type (e.g., preview and production in my case) and ensure the build process is properly declared in eas.json
(with the following nest :

"build": 
    { "your_environment_name": 
        { "environment": "preview", // or production, development

)

I had multiple variables with identical names on the Expo dashboard, all prefixed with EXPO_PUBLIC_. The difference between them was the build environment they were associated with (e.g., preview or production). These prefixes were necessary because the variables needed to be available directly in my code, removing them didn't work.

I accessed these variables in my code using process.env. However, attempting to retrieve them elsewhere with a dynamic approach, such as:

  const envValue = process.env["EXPO_PUBLIC_MY_VALUE"];
   return envValue;

did not work for me (took me a long time to figure it out, dynamic call after build doesn't seem to work).

I've got non prefixed variables but they are only for build purpose. process.env reach them during build.

Hope this will help someone !

Have a nice day

@tharakadesilva
Copy link

Setting up Supabase with Expo Updates and EAS

If you're struggling with Supabase integration, here's what worked for me:

Understanding the Issue

Environment variables are being picked up during the build phase but not during updates, as updates don't get access to env vars from Expo directly.

My Setup

Key Solution: Using Environment Flag

The crucial part is using --environment during expo update to attach the environment variables.

Step-by-Step Implementation

  1. Create Environment Variables in Expo

  2. Update eas.json

  3. Important Documentation Note

    When the --environment flag is provided, eas update will use the environment variables on EAS servers for and won't use the .env files present in your project. Expo CLI will substitute prefixed variables in your code (for example,process.env.EXPO_PUBLIC_VARNAME) with the corresponding plain text and sensitive environment variable values set on EAS servers for the environment specified with the --environment flag.

    Any EXPO_PUBLIC_ variables in your application code will be replaced inline with the corresponding values from your EAS environment whether that is your local machine or your CI/CD server.

    We recommend using the --environment flag to ensure the same environment variables are used both for your update and build jobs.

  4. Accessing Variables
    Use process.env.EXPO_PUBLIC_SUPABASE_URL and process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY

Now, when your app is built / an update is published, the env variable will be available for the app! 🎉

For GitHub Actions Users

If using continuous-deploy-fingerprint:

  1. Currently awaiting this change to be merged
  2. Temporary solution: Use uses: tharakadesilva/expo-github-action/continuous-deploy-fingerprint@main
  3. Set environment in your action config:
    environment: ${{ github.event_name != 'pull_request' && 'production' || 'development' }}
    

@suhascv
Copy link

suhascv commented Dec 13, 2024

can't believe this issue has been open for over two years and still has no support from expo team. 😠

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs review Issue is ready to be reviewed by a maintainer
Projects
None yet
Development

No branches or pull requests