React Native Notes – 002
Published
OTA updates
The JavaScript bundle in your app (the "React" part of React Native) can be swapped-out in live apps. So if you want to fix a simple typo or even add a new screen to your app, you can update this bundle and your app will fetch it the next time its user opens it.
To enable over-the-air updates for your app, you need to add the expo-updates
package to your project. This will be automatically installed the first time you run eas update
(or you can manually install it with npx expo install expo-updates
).
While you've been developing your app locally, you'll have been running a local server from your machine (via the npx start
command). The standard eas.json
build.development
configuration (i.e. "developmentClient": true
) will have let you build an app that you can install on a device and this app will look to your local server for the JS bundle, fetching code changes as they happen (i.e. hot module reloading). eas update
pretty much allows you to do the equivalent but with your production app.
When you run eas update --auto
from your terminal, the eas cli will build your app bundle locally and then upload it to the Expo servers. It will use the name of your current git branch as the name of your Expo update branch (that's what the --auto
flag does).
Now – bear with me – this Expo update branch needs to be linked to an Expo channel and channels are then associated with actual builds. So your production
build would typically be associated to your main
channel, which is linked to your main
branch (where main
is the name of your git branch and also your Expo update branch)
You can link any Expo branch to any Expo channel, this is done by running the following command (assuming that I want to link my "preview" channel and an Expo branch named feature/foo
):
eas channel:edit preview --branch feature/foo
At the moment I'm leaning towards keeping the channel names the same as the branch names. It seems a bit simpler, one less thing for me to have to remember; I can just simply run eas update --auto
and not have to worry about it any further.
To associate a build with an update channel, you need to specify the channel
property in your eas.json
file:
{
"cli": {
"version": ">= 5.3.0"
},
"build": {
"production": {
"node": "18.17.0",
"channel": "main"
},
"preview": {
"extends": "production",
"distribution": "internal",
"channel": "preview"
}
}
}
Note that if this is your first time setting-up the eas update functionality, you will need to do another eas build
after you've added the expo-updates
package. The newest build will then be capable of fetching updates from the Expo servers.
Why hasn't my app updated?
There are a few reasons why updates may not appear on your device:
1. Configuration
Make sure that you have:
- Run
npx expo install expo-updates
- Set channels for your build configurations (in
eas.json
) - Have run an
eas build
after doing the above 2 things - Have run an
eas update
after making a simple code change - Your Expo update branch is linked to the channel that is associated with the build that you are testing.
- Your changes haven't changed the app version or any native code.
2. Timing
If your app is able to download both the update manifest and all the required assets before the fallbackToCacheTimeout
setting, then the new update will run immediately upon launch. If not, it will continue to download the update in the background and will run it upon the next launch.
By default fallbackToCacheTimeout
is 0ms. So, unless you've specified anything greater, this is the primary culprit of why you're not seeing immediate app updates.
You can set this value in your app.json
file in the udpates
section.
3. Usage limits
Go to the Expo dashboard and navigate to Account Settings > Usage. Make sure that you haven't gone past your limit of updates. Stick in your credit card details if you have or, potentially, host your own Expo updates server.
Summary
Now that I've got my head around branches and channels, I'm loving EAS. It really does take a lot of the grunt work out of app development. When I get a chance I'll setup a Github action to automate as much of this as I can; that'll be sweet.
Other random brain stuff I need to write down
There is a bit of a disconnect for me in that you could be on a git branch called feature/foo
and then run eas build --profile preview --platform ios
. That preview app will come bundled with the code in you branch. This makes sense. However, if I were then to fix a typo and run eas update --auto
then a new Expo branch and a new Expo channel would be created (named feature/foo
) but this code would not be pushed to instances of the preview app, that's because the preview app is not associated with the channel that the update was deployed to.