TL;DR We get a handful of āCannot download [assetlink on Cloudfront]ā errors on Sentry, leading me to think the crash might have something to do with the asset caching code done during the AppLoading
screen - might there be some issue for clean installs and assets provided OTA (that are not a part of a binary?)
It occurred to me recently that since the userās did get to see our AppLoading
splash, that the error might be related to the asset caching code that runs while it shows. Itās pretty much copy+paste from the guide in the docs, but Iām running out of ideas.
A short summary here:
AppContainer.tsx
const loadAssets = async () => await loadAndCacheAssets();
if (!isReady) {
return (
<GenericErrorBoundary prefix="AppLoading">
<AppLoading startAsync={loadAssets} onFinish={() => setIsReady(true)} onError={handleLoadingError} />
</GenericErrorBoundary>
);
}
// else return full app
export const loadAndCacheAssets = async () => {
try {
// Cache bundled image assets
const imageAssets = await cacheImages(getAllImagesFromAssets());
// Cache remote fonts and font icons
const fontAssets = cacheFonts([
FontAwesome.font,
// ...other fonts
]);
// Download and cache locally bundled fonts
const loadFonts = Font.loadAsync(require('./../assets/fonts/RobotoRegular.ttf'));
await Promise.all([...imageAssets, ...fontAssets, loadFonts]);
} catch (error) {
console.log(`Error loading assets\n${error}`);
captureException(error);
}
};
const cacheImages = async (images: any[]) => {
return await images.map(async (image: any) => {
if (typeof image === 'string') {
return Image.prefetch(image);
} else {
try {
return await Asset.fromModule(image).downloadAsync();
} catch (e) {
console.warn(`There was an error downloading an image. The error was: ${e}`);
captureException(e);
}
}
});
};
const cacheFonts = (fonts: any) => {
return fonts.map((font: any) => Font.loadAsync(font));
};
const getAllImagesFromAssets = () => {
const appIcons = Object.keys(Images.appIcons).map(key => Images.appIcons[key]);
const backgrounds = Object.keys(Images.backgrounds).map(key => Images.backgrounds[key]);
const images = Object.keys(Images.images).map(key => Images.images[key]);
const tabBarIcons = Object.keys(Images.tabbarIcons).map(key => Images.tabbarIcons[key]);
return [...appIcons, ...backgrounds, ...images, ...tabBarIcons, Images.curvedArrow, Images.pushPermissionButton];
};
Images.ts
export const Images = {
appIcons: {
shopIcon: require('./../assets/icons/shop-icon.png'),
// ... other icons
},
images: {
wink: require('./../assets/images/wink.gif'),
// more images
},
// and some more...
};
I then found some errors on Sentry that might confirm my suspicion - a lot of
Could not download from 'https://d1wp6m56sqw74a.cloudfront.net/~assets/1bc5a7992af35c03a9323043b2efe23a
where the assets vary, but are all some of the assets that are bundled with the app.
The issue seems to mostly affect new (re)-installs of the app - might there be some issue with OTA updates for assets?