Can't communicate with the server ( i presume a issue with env environment)

Hi everyone,

It’s the first time i create an app and i’m having some issues with EAS and the env variable (I think so). I’ve created an app for a burger restaurant and everything work on my local and when i publish the app a release channel with expo publish --release-channel production-v1.

Now, it’s time to publish my app in the stores, so i would like to create the build for my code in the eas environment and submit into the stores.
I’ve read the documentation but something is missing in my configuration because i tested the app in my android device( throughout a generated apk) and it cannot communicate with the backend server ( I presume that this is the problem because i show a view in this case and i can see it ).

This is my current configuration for eas.json.

{
  "cli": {
    "version": ">= 0.38.3"
  },
  "build": {
    "development": {
      "releaseChannel": "development",
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {
      "releaseChannel": "production",
      "android": {
        "buildType": "apk"
      },
      "env": {
        "RELEASE_CHANNEL": "production"
      }
    }
  },
  "submit": {
    "production": {}
  }
}

There is an env variable RELEASE_CHANNEL which i use in my source code to choose between extra.server configuration

This is the configuration for app.config.js

export default ({ config }) => {
  return {
    ...config,
    hooks: {
      postPublish: [
        {
          file: "sentry-expo/upload-sourcemaps",
          config: {
            organization: process.env.SENTRY_ORG,
            project: process.env.SENTRY_PROJECT,
            authToken: process.env.SENTRY_AUTH_TOKEN,
            setCommits: true,
          },
        },
      ],
    },
    extra: {
      server: {
        local: process.env.EXPO_LOCAL_SERVER,
        development: process.env.EXPO_DEVELOPMENT_SERVER,
        production: process.env.EXPO_PRODUCTION_SERVER,
      },
      secret: {
        development: process.env.EXPO_JWT_SECRET_DEVELOPMENT,
        production: process.env.EXPO_JWT_SECRET_DEVELOPMENT,
      },
      mapsToken: process.env.GOOGLE_MAPS_KEY,
      placesToken: process.env.PLACES_API,
    },
    plugins: ["expo-updates", "expo-dev-client"],
  };
};

and the file in my source code where i choose the extra.server variable

const getEnvironment = () => {
  let releaseChannel = process.env.RELEASE_CHANNEL ?? Constants.manifest.releaseChannel;

  if (releaseChannel === undefined)
    // since releaseChannels are undefined in dev, return your default.
    return getObjectEnvironment(
      Constants.manifest.extra.server.local,
      Constants.manifest.extra.secret.development,
      Constants.manifest.extra.mapsToken,
      Constants.manifest.extra.placesToken
    );
  if (releaseChannel.indexOf("development") !== -1)
    // this would pick up development-v1, development-v2 ...
    return getObjectEnvironment(
      Constants.manifest.extra.server.development,
      Constants.manifest.extra.secret.development,
      Constants.manifest.extra.mapsToken,
      Constants.manifest.extra.placesToken
    );
  if (releaseChannel.indexOf("production") !== -1)
    // this would pick up production-v1, production-v2 ...
    return getObjectEnvironment(
      Constants.manifest.extra.server.production,
      Constants.manifest.extra.secret.production,
      Constants.manifest.extra.mapsToken,
      Constants.manifest.extra.placesToken
    );
};

These are my env variable on my local environment. Of course, i added all of these varibles (except EXP_LOCAL_SERVER) into my secret section for my app in the expo configuration.

# SERVERS
EXPO_LOCAL_SERVER=XXX
EXPO_DEVELOPMENT_SERVER=XXX
EXPO_PRODUCTION_SERVER=XXX


# AUTHENTICATION TOKEN
EXPO_JWT_SECRET_DEVELOPMENT=XXX

# GOOGLE MAPS KEY
GOOGLE_MAPS_KEY=XXX
PLACES_API=XXX

# SENTRY_ORG
SENTRY_PROJECT=XXX
SENTRY_ORG=XXX
SENTRY_AUTH_TOKEN=XXXX

This is my mental flow ( let me know if i am wrong) how work the build process with env environment. The build process set the variables into process.env so in the app.config.js files are available and are used to set the Constants.manifest.extra properties. Then in my source code, i use process.env.RELEASE_CHANNEL variable which is defined in eas.json file to choose the correct environment. In case this variable is not defined , i use Constants.manifest.releaseChannel to publish the app into expo or for my local development.

I am using a managed flow, so i can’t use the development environment ( expo start --dev-client) to test it because when i run the previous command, the output says that i need a bare flow

so, what is wrong?

btw, my eas-cli version is eas-cli/0.38.3 linux-x64 node-v14.18.1

Thanks in advance

You are only setting "RELEASE_CHANNEL": "production" in eas.json, where are the other envs defined?

For build to work they have to be present in eas.json build profile or in EAS secrets

anything that you specify in your local environment will affect app.config.js when it’s resolved locally, but if those envs are not present on eas worker then app.config.js will resolve to sth different during actual build

Yes, because i only run the production environment. Anyway, I just added to the development profile and i tried again running eas build --platform android but the problem persist. This is my new eas,json

{
  "cli": {
    "version": ">= 0.38.3"
  },
  "build": {
    "development": {
      "releaseChannel": "development",
      "developmentClient": true,
      "distribution": "internal",
      "env": {
        "RELEASE_CHANNEL": "development"
      }
    },
    "production": {
      "releaseChannel": "production",
      "android": {
        "buildType": "apk"
      },
      "env": {
        "RELEASE_CHANNEL": "production"
      }
    }
  },
  "submit": {
    "production": {}
  }
}

Is there any way to see if the secrets are injected properly in the building process?

I was asking where are the other envs defined EXPO_PRODUCTION_SERVER, GOOGLE_MAPS_KEY …

Is there any way to see if the secrets are injected properly in the building process?

Yes, list of all envs from eas.json (key+values) and secrets (just keys) are printed in Spin up build environment section of the logs

I was asking where are the other envs defined EXPO_PRODUCTION_SERVER, GOOGLE_MAPS_KEY

There are defined in secret section in the project

I uploaded a new version of the app showing in the error screen all values of the env variables and i now i am sure that the problem is because the server URL is not set during the process of building, so i will investigate why is happening

I just identified the issue.

  let releaseChannel = process.env.RELEASE_CHANNEL ?? Constants.manifest.releaseChannel;

  if (releaseChannel === undefined)
    // since releaseChannels are undefined in dev, return your default.
    return getObjectEnvironment(
      Constants.manifest.extra.server.local,
      Constants.manifest.extra.secret.development,
      Constants.manifest.extra.mapsToken,
      Constants.manifest.extra.placesToken
    );

The releaseChannel variable is undefined so it goes inside in the first if where the Constants.manifest.extra.server.local is undefined (because the EXPO_LOCAL_SERVER is not defined in project secret).

I’ve added EXPO_LOCAL_SERVER in the secret sections and everything is fine, so my question is , why process.env.RELEASE_CHANNEL comes with not value if in my eas.json file is defined and in the log for the build process i can see it ? :thinking:

Project environment variables:
  RELEASE_CHANNEL=production

Finally, it works. My fault was used the process.env in my “code” instead of app.config.json.
I’ve added a new variable inside the app.config.js with the value of the process.env.RELEASE_CHANNEL and then i can use in my code.

import "dotenv/config";

export default ({ config }) => {
  return {
    ...config,
    hooks: {
      postPublish: [
        {
          file: "sentry-expo/upload-sourcemaps",
          config: {
            organization: process.env.SENTRY_ORG,
            project: process.env.SENTRY_PROJECT,
            authToken: process.env.SENTRY_AUTH_TOKEN,
            setCommits: true,
          },
        },
      ],
    },
    // All values in extra will be passed to your app.

    extra: {
      releaseChannel: process.env.RELEASE_CHANNEL,
      server: {
        local: process.env.EXPO_LOCAL_SERVER,
        development: process.env.EXPO_DEVELOPMENT_SERVER,
        production: process.env.EXPO_PRODUCTION_SERVER,
      },
      secret: {
        development: process.env.EXPO_JWT_SECRET_DEVELOPMENT,
        production: process.env.EXPO_JWT_SECRET_DEVELOPMENT,
      },
      mapsToken: process.env.GOOGLE_MAPS_KEY,
      placesToken: process.env.PLACES_API,
    },
    plugins: ["expo-updates", "expo-dev-client", "expo-location"],
  };
};

and

const getEnvironment = () => {
  let releaseChannel = Constants.manifest.extra.releaseChannel ?? Constants.manifest.releaseChannel;

  if (releaseChannel === undefined)
    // since releaseChannels are undefined in dev, return your default.
    return getObjectEnvironment(
      Constants.manifest.extra.server.local,
      Constants.manifest.extra.secret.development,
      Constants.manifest.extra.mapsToken,
      Constants.manifest.extra.placesToken
    );
  if (releaseChannel.indexOf("development") !== -1)
    // this would pick up development-v1, development-v2 ...
    return getObjectEnvironment(
      Constants.manifest.extra.server.development,
      Constants.manifest.extra.secret.development,
      Constants.manifest.extra.mapsToken,
      Constants.manifest.extra.placesToken
    );
  if (releaseChannel.indexOf("production") !== -1)
    // this would pick up production-v1, production-v2 ...
    return getObjectEnvironment(
      Constants.manifest.extra.server.production,
      Constants.manifest.extra.secret.production,
      Constants.manifest.extra.mapsToken,
      Constants.manifest.extra.placesToken
    );
};

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.