Can't configure eas update

Hi,

I got stuck in the eas update configuration.

If I type eas update:configure I get the following error:

It looks like you are using a dynamic configuration! Learn more: https://docs.expo.dev/workflow/configuration/#dynamic-configuration-with-appconfigjs)
In order to finish configuring your project for EAS Update, you are going to need manually add the following to your app.config.js:
Learn more: https://expo.fyi/eas-update-config.md

{
  "runtimeVersion": {
    "policy": "sdkVersion"
  },
  "android": {
  ...
  },
  "ios": {
    ...
  },
  "updates": {
    "fallbackToCacheTimeout": 0,
    "url": "https://u.expo.dev/c21606c0-d0cc-11e9-a631-b54ba6577995"
  }
}

 Error: Cannot automatically write to dynamic config at: app.config.js

I get that something is wrong with my app.config.js file, which is configured like this:

module.exports = () => {
  if (process.env.APP_ENV === "production") {
    return require("./app-production.json");
  } else if (process.env.APP_ENV === "staging") {
    return require("./app-staging.json");
  } else {
    return require("./app-development.json")
  }
}

the json files differ only in name, slug, bundleIdentifier (iOS), package (android) and look like:

{
  "expo": {
    "name": "Name",
    "scheme": "name",
    "description": "This project is really great.",
    "slug": "name",
    "privacy": "unlisted",
    "sdkVersion": "45.0.0",
    "platforms": [
      "ios",
      "android"
    ],
    "version": "1.2.11",
    "orientation": "portrait",
    "icon": "./images/appicon.png",
    "splash": {
      "image": "./images/splash_new.png",
      "resizeMode": "cover",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "plugins": [
      "./plugins/withAndroidVerifiedLinksWorkaround"
    ],
    "ios": {
      "bundleIdentifier": "com.comp.name.prod",
      "buildNumber": "1",
      "supportsTablet": false,
      "config": {
        "googleMapsApiKey": "AIzaSyAsaMRyRtPIyba-DI3U0LgG-Yi4g3S8EIE"
      },
      "infoPlist": {
        "LSApplicationQueriesSchemes": [
          "comgooglemaps",
          "citymapper",
          "uber",
          "lyft",
          "waze",
          "instagram",
          "instagram-stories"
        ],
        "NSCameraUsageDescription": "The app needs permission to your camera in order to take photos for your profile image",
        "NSPhotoLibraryUsageDescription": "The app needs permission to your camera roll in order to add a profile image",
        "NSLocationWhenInUseUsageDescription": "Trppn will use our location to show you venues and events in your direct area"
      },
      "associatedDomains": [
        "applinks:trppncreator.net"
      ]
    },
    "android": {
      "package": "com.comp.name",
      "versionCode": 45,
      "useNextNotificationsApi": true,
      "googleServicesFile": "./google-services.json",
      "config": {
        "googleMaps": {
          "apiKey": "AIzaSyDaI_Oa-Mm64hXSnPnRIruENWT_RupWPlU"
        }
      },
      "permissions": [
        "ACCESS_COARSE_LOCATION",
        "ACCESS_FINE_LOCATION",
        "CAMERA"
      ],
      "intentFilters": [
        {
          "action": "VIEW",
          "autoVerify": true,
          "data": [
            {
              "scheme": "https",
              "host": "trppncreator.net",
              "pathPrefix": "/universal"
            }
          ],
          "category": [
            "BROWSABLE",
            "DEFAULT"
          ]
        }
      ]
    },
    "notification": {
      "iosDisplayInForeground": true
    }
  }
}

Note: Since I haven’t figured out how to set/adjust this dynamic config for eas build, I manually copy the resp. app-*.json file into app-development.json and type eas build and this at least works for making builds. But for eas, it seems that APP_ENV= is being ignored.

Now I don’t know how eas update works, but it looks like it’s not taking the app-develompment.json file like eas build…

The goal would be to get configure the project (json files and app.config.js) in a way that

  1. command: eas update:configure works so that I can use eas update

  2. an equivalent to command APP_ENV=... eas build (so I dont have to do copy+pasting of json files)

  3. If possible: not change the process in a way, that expo still works like before, e.g. APP_ENV=production expo start, if this isn’t possible its not too bad, I can still use the dev-client

Additional Infos:

  • Managed Workflow
  • eas-cli 1.2.0

Hope that someone has an idea!

BR,
Marko

Hi @mksquad

It just means that Expo cannot interpret arbitrary JavaScript code (your app.config.js) to know how to add that config, so you need to add it yourself.

So basically, you’ll need to edit your app-*.json files to add a "runtimeVersion" section and an "updates" section something like the following, but check the docs, because you might want to choose a different "policy":

  "runtimeVersion": {
    "policy": "sdkVersion"
  },
  "updates": {
    "fallbackToCacheTimeout": 0,
    "url": "https://u.expo.dev/c21606c0-d0cc-11e9-a631-b54ba6577995"
  }

If you build locally on your own machine (eas build --local ...) then it should work as you expect. If you build on Expo’s build servers then you should also specify the environment variables in eas.json:

{
[...]
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "env": {
        "APP_ENV": "development"
      }
    },
    "preview": {
      "distribution": "internal",
      "env": {
        "APP_ENV": "staging"
      }
    },
    "production": {
      "env": {
        "APP_ENV": "production"
      }
    },
  },
[...]
}

Whenever you execute expo or eas commands you should make sure you specify the APP_ENV environment variable so that Expo can find the correct config. So:

APP_ENV=xxx eas_update:configure

But, I’m a little unsure of this: You have different bundle IDs/packages specified for the different app environments. I’m not sure if the update URL will need to differ too. But I think it can be the same across dev/staging/production.

As mentioned above, you’ll need to add the APP_ENVs to your EAS Build profiles, and you will still need to also call APP_ENV=... eas build ...

I’m not 100% sure what you mean by the above. Presumably you would not run the production version in Expo Go, since it is the same as the dev/staging versions (other than the name and bundle/package IDs)?

APP_ENV=development expo start should work fine for the dev client. Depending on what dependencies you have installed it might also work fine for Expo Go.

By the way, at the moment you’re duplicating everything in your three versions of app.json. What I would do instead is keep all of the common code in app.json and then only override the name, bundleIdentifier and package in app.config.js.

Something like this:

app.json:

{
  "expo": {
    "name": "Picovoice Demo",
    "slug": "picovoice-test",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true,
      "infoPlist": {
        "NSMicrophoneUsageDescription": "Allow $(PRODUCT_NAME) to access your microphone for voice commands"
      },
      "bundleIdentifier": "com.example.picoVoice"
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#FFFFFF"
      },
      "permissions": [
        "RECORD_AUDIO"
      ],
      "package": "com.example.picoVoice"
    },
    "web": {
      "favicon": "./assets/favicon.png"
    }
  }
}

app.config.js:

function app_env(base, dev, preview) {
  switch (process.env.APP_ENV) {
    case "development":
      return `${base}${dev}`;
    case "preview":
      return `${base}${preview}`;
    default:
      return base;
  }
}

export default function ({ config }) {
  return {
    ...config,
    name: app_env(config.name, " (Dev)", " (Preview)"),
    android: {
      ...config.android,
      package: app_env(config.android.package, ".dev", ".preview"),
    },
    ios: {
      ...config.ios,
      bundleIdentifier: app_env(config.ios.bundleIdentifier, ".dev", ".preview"),
    },
  };
}

Then you don’t need your separate app-development.json, app-staging.json and app-production.json.

1 Like

hi @wodin,

thanks for the detailed answer!

So they APP_ENV=... eas ... is working now, after I added those env vars into the eas.json as you suggested. :slight_smile: Thanks for that!

Now concerning the other problem with eas update:config:
This is still not working (although it is taking the right app-*.json file according to what I set in APP_ENV=* eas update:configure)

My app-production.json for example, is now looking like this:

{
  "expo": {
  "extra": {
        "eas": {
          "projectId": "<large id>"
        }
    },
    "name": "Name",
    "scheme": "name",
    "description": "This project is really great.",
    "slug": "name",
    "privacy": "unlisted",
    "sdkVersion": "45.0.0",
    "platforms": [
      "ios",
      "android"
    ],
    "version": "1.2.11",
    "orientation": "portrait",
    "icon": "./images/appicon.png",
    "splash": {
      "image": "./images/splash_new.png",
      "resizeMode": "cover",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "plugins": [
      "./plugins/withAndroidVerifiedLinksWorkaround"
    ],
   "runtimeVersion": {
      "policy": "sdkVersion"
    },
    "android": {
         ....
    },
    "ios": {
         ....
    },
    "notification": {
      "iosDisplayInForeground": true
    },
    "updates": {
      "fallbackToCacheTimeout": 0,
      "url": "https://u.expo.dev/c21606c0-d0cc-11e9-a631-b54ba6577995"
    }
  }
}

But it still tells me:

It looks like you are using a dynamic configuration! Learn more: https://docs.expo.dev/workflow/configuration/#dynamic-configuration-with-appconfigjs)
In order to finish configuring your project for EAS Update, you are going to need manually add the following to your app.config.js:
Learn more: https://expo.fyi/eas-update-config.md

{
  "runtimeVersion": {
    "policy": "sdkVersion"
  },
  "android": {
    ...
  },
  "ios": {
   ...
  },
  "updates": {
    "fallbackToCacheTimeout": 0,
    "url": "https://u.expo.dev/c21606c0-d0cc-11e9-a631-b54ba6577995"
  }
}

    Error: Cannot automatically write to dynamic config at: app.config.js

but the app-production.json already has all these fields… :thinking:

PS: concerning the restructuring to only one json file: thanks for the tip, this solution is way cleaner :slight_smile:

BR

hmmm… I think it should be more intelligent and be able to detect that the necessary changes have already been made to your app config. But it seems like it just sees that you’re using app.config.js and gives up. I think it’s reasonable to give up trying to make the modifications, but it should be able to check if the necessary runtimeVersion.policy and updates.url are already there.

But anyway, as long as you have added that stuff to your app config, my understanding is you don’t need to run eas update:configure.

Hi @wodin ,

yeah you were right! I didn’t even need the :config part, APP_ENV=staging eas update worked!

But there is another problem: I can’t see the changes that I updated an committed…
I tested that on our staging and production:

  1. I changed some string and made a new commit on the master branch
  2. I ran APP_ENV=production eas update

Result:

[expo-cli] [09:52:09] Export was successful. Your exported files can be found in dist
âś” Built bundle!
âś” Uploaded 2 assets!
âś” Created branch: master
âś” Created a channel: master pointed at branch: master.
âś” Published!

Problem: when I open the standalone app, I cannot see the update…

So my question is: shouldn’t eas update work in the same way as expo publish, i.e. publishing over-the-air updates, also to the standalone versions on the app stores?
If yes, what did I mess up in my config again? :see_no_evil:

BR

Yes, it should. I have not really done much with eas update myself yet, so I’m not sure what else might be wrong in your case. I assume you did install expo-updates before building your current production app, right?

See also: Debugging guide - Expo Documentation

Hi @wodin,

so I read the link you send me and it turned out that my production channel was in the eas.json but when I typed eas channel:list it only showed the branch that was created by eas update so I added the production channel (and automatically it creates the production branch as well) via eas channel:create and after I ran eas update --branch production it worked :partying_face:

Thanks so much for your help!

1 Like

Great! :slight_smile: Thanks for following up

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