Clarification on automatic OTA updates

From the documentation:

By default, Expo will check for updates automatically when your app is launched and will try to fetch the latest published version. If a new bundle is available, Expo will attempt to download it before launching the experience. If there is no network connection available, or it has not finished downloading in 30 seconds, Expo will fall back to loading a cached version of your app, and continue trying to fetch the update in the background (at which point it will be saved into the cache for the next app load).

Just to clarify, does “launched”, means from when the app is killed and then they start it, or can it happen when the app is backgrounded and foregrounded?

Based on what I’m experiencing I think “launched” means that the app has to be killed and fresh started.

If this is true, can one add “manual updates” mixed in with automatic updates for the cases when the app goes from backgrounded to foregrounded (which happens a majority of the time)?


SDK 38.

1 Like

Yes, the app needs to be restarted, not just brought to the foreground.

I have not used the new Updates module yet, but yes, you can manually check for/download updates and prompt the user to restart in addition to the automatic updates.

1 Like

Got it, this is what I experience as well, but I think this thread will serve to clarify for others new to Expo.

I basically still have the hard-start OTA updates working as default, but added additional logic to download while the application is running and update when it gets foregrounded (not hard-start).

1 Like

Hello,
expo automatic OTA upgrades are great, but if you want a deterministic way to ensure that the last published code is always displayed it is better manage updates manually.
Also some users never closes their app (preventing cached update to load on app restart) so it is important to also check for updates on app state changes (background to foreground).

I did it in many apps (manual checks are delicate, if your code crash for any reason doing it app become stuck in update cycle).

To avoid copy paste I published a small npm that does just that, maybe you can find an use for it :slight_smile:
https://www.npmjs.com/package/expo-custom-updater

This is awesome! Thanks for sharing.

I implemented a solution very similar to yours except a few things:

  1. I didn’t turn off the auto updates from a cold-start. I found that this is happening before the app loads in and doesn’t get in the way. If they cold-start and update, by the time the custom checking code runs, it will see that it is up-to-date
  2. I actually poll once per minute and fetch the bundle (if the app is open at all, even when backgrounded). Then when the user foregrounds the app, I simply refresh. I think this provides for a smoother experience after my testing.

Thanks :slight_smile:
We preferred to explicitly show a “loading” spinner so we can also check the App version against the build in the App Store, so in case we pushed a new build to the stores and user is running an old one (therefore making the publish pointless as we don’t have one release channel per build) we can display a “Please update this app via App Store to get the best experience”, or completely lock the user out of the app depending from the app use case.

1 Like

I was looking at the code. Where is the place where you determine if a completely new version from the app store needs to be downloaded?

Also, when we do upgrade to say SDK 39 and release a new version to the app store, will we need to publish to a different release channel? Would it break for people with SDK 38?

Hi Aryk,
The code itself to check the binary code is a simple REST get to our API server that replies with the current version then compared to the app.js manifest.
As this was literally one line of logic and a page of UI code, it is using our API server and it was outside the concern of OTA updates it was not included in this small lib :slight_smile:

About your question: In expo you can have release channels beside the default, we use a “dev” channel to build a binary .apk to test and publish specific stuff without disturbing the production channel.

You may consider every Expo SDK as having a separate “default” release channel, so when upgrading to 39 and publishing an update, that pushed code only goes to the “default channel 39” and made available only to App built on 39.

Users that do not update your app will stay on 38 and no longer receive updates, unless you have a branch of your code still on 38 and merge / publish your changes from there. It’s possible to handle it this way (maybe only for emergency bugs), but not ideal.

For that reason on some app we enforce the update: after a week that the app is on the stores we bump the version provided by the REST service and every user still on the old one will have the App locked with an info screen and a redirect on the store page.

Hope that helps

1 Like

No. An app built with SDK 38 will never try to download a bundle built against a different SDK.

https://docs.expo.io/workflow/publishing/#what-version-of-the-app-will-my

2 Likes

Old school, but it works:

1 Like

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