We’ve been building a bare workflow app for release and have faced some issues with expo-updates@0.2.2
and assets management on Android.
Runtime Version
The first weird thing was that in the docs it specified that runtimeVersion
should be an “An object with keys ios
and android
whose corresponding values are the runtime version this update is compatible with.”
So, in our app.json we had something like this:
"runtimeVersion": {
"ios": "1",
"android": "1"
}
Having the json structured this way made expo-updates
consistently fail to find the update on android (Updates.manifest = {}
), and we had an error in cli saying that runtimeVersion
should be a string.
When we set "runtimeVersion": "1"
and Updates.manifest
started to be populated again.
We had a look into the expo-updates
Android code and found out that there are 3 types of manifest; bare, legacy and new (expo-cli@3.20.9
).
The manifest we generate seems to match the legacyManifest
, in fact in the function that parses the json it tries to handle both string and object for runtimeVersion
. Code for this is here:
if (runtimeVersionObject != null) {
if (runtimeVersionObject instanceof String) {
runtimeVersion = (String)runtimeVersionObject;
} else if (runtimeVersionObject instanceof JSONObject) {
runtimeVersion = ((JSONObject)runtimeVersionObject).optString(“android”, runtimeVersion);
}
}
But it also seems that a legacyManifest should match this config:
expo.modules.updates.EXPO_LEGACY_MANIFEST
Questions
- However we do not set this parameter, so how does this work?
- Why don’t we have a bareManifest, when in a bare workflow?
assetUrlOverride Not Constructed Correctly
With the above fix and the manifest being parsed correctly, the update still fails due to wrong asset urls when using assetUrlOverride
to set an absolute path for the assets. With this our hosted android-index.json
would contain:
"assetUrlOverride": "https://xxx.cloudfront.net/yyy/3dd28fbbf/native/bare/assets",
This has always worked fine for iOS, however on android the update fails because it looks for assets and appends assetUrlOverride
to the updates host url. We are setting the EXPO_UPDATE_URL
with:
<meta-data android:name=“expo.modules.updates.EXPO_UPDATE_URL” android:value=“https://xxx.com/pocket/jkTTiukljhe12kl2sF2d3/android-index.json” />
This results in something like:
https://xxx.com/pocket/jkTTiukljhe12kl2sF2d3/https%3A%2F%2Fxxx.cloudfront.net%yyy%2F055d780a0%2Fnative%2Fbare%2Fassets/0ec7d3a4f6643fca50b88f4e2efd5898
We also noticed the URL is only partially encoded.
To resolve this issue we have patched this code.
- In order to have the builder to get instantiated as empty:
Uri.Builder assetsBaseUrlBuilder = new Uri.Builder();
- Properly handle the encoded path:
assetsBaseUrlBuilder.encodedPath(assetsPath);
The resulting code looks like:
if (mAssetsUrlBase == null) {
// use manifest url as the base
String assetsPath = getRawManifestJson().optString("assetUrlOverride", "assets");
Uri.Builder assetsBaseUrlBuilder = new Uri.Builder();
List<String> segments = manifestUrl.getPathSegments();
assetsBaseUrlBuilder.path("");
for (int i = 0; i < segments.size() - 1; i++) {
assetsBaseUrlBuilder.appendPath(segments.get(i));
}
assetsBaseUrlBuilder.encodedPath(assetsPath);
mAssetsUrlBase = assetsBaseUrlBuilder.build();
}
Questions
3. How is this intended to work?
With all of the above we now have expo-updates
working on Android, hosted on our own server with an assetUrlOverride
set. Has anyone else managed to get this working without the above?