• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

? Fixing Image Asset Issues in OTA Updates for React Native: Overcoming Stale Assets After Updates

Lomanu4 Оффлайн

Lomanu4

Команда форума
Администратор
Регистрация
1 Мар 2015
Сообщения
1,481
Баллы
155
After implementing a manual OTA (Over-The-Air) update system for my React Native app, I ran into a major limitation: images imported via require() don’t update with the JS bundle. React Native statically bundles assets during build time, so even after a successful OTA update, the images remained stale.

To solve this, I created a flexible system where image assets are:

  • Organized by screen density (drawable-mdpi, hdpi, etc.),
  • Zipped into a single file,
  • Hosted on Firebase Hosting,
  • Downloaded and unzipped at runtime,
  • Loaded dynamically using file URIs.

Here’s exactly how I did it:

? Step 1: Organizing the Asset Bundle (ota-bundles)


My folder structure looks like this:


?ota-bundles/
┣ ?drawable-mdpi/
┃ ┣ ?assets_workoutimage_triceps_tricepdips.webp
┃ ┣ ?node_modules_reactnativecalendars_src_img_down.png
┃ ┗ ?... more images
┣ ?drawable-hdpi/
┣ ?drawable-xhdpi/
┣ ?drawable-xxhdpi/
┣ ?drawable-xxxhdpi/
┣ ?index.android.bundle ← OTA JS bundle
┣ ?version.json ← Version tracking file
┣ ?index.html, 404.html ← Firebase placeholders
┗ ?ota-bundles.zip ← Zipped OTA bundle

Inside each drawable-* folder, I placed all relevant image assets including custom app images and auto-extracted images used by third-party libraries (like react-native-calendars, react-navigation, etc.).

? Step 2: Zipping the Asset Bundle


Once my folder structure was ready, I zipped the entire ota-bundles folder:


zip -r ota-bundles.zip ota-bundles/

This produced ota-bundles.zip, which contains:

  • index.android.bundle (JS code),
  • drawable-* folders (images),
  • version.json (to detect updates).

This .zip file is what my app will download during an update.

☁ Step 3: Hosting the Zip File on Firebase Hosting


Firebase Hosting provides a reliable and fast CDN for serving static files.

Setup


  1. Now host the whole ota-bundles.


  2. Run:

firebase deploy --only hosting
  1. After deployment, Firebase gives you a public URL:


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



This URL is then used in the app to download the update.

? Step 4: Downloading & Unzipping the Assets at Runtime


In your React Native app, you handle this zip file using react-native-fs and react-native-zip-archive:


import RNFS from 'react-native-fs';
import { unzip } from 'react-native-zip-archive';

const ZIP_URL = '

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.


const LOCAL_ZIP = `${RNFS.DocumentDirectoryPath}/ota-bundles.zip`;
const EXTRACT_PATH = `${RNFS.DocumentDirectoryPath}/ota-bundles`;

export const downloadAndExtractBundle = async () => {
// Step 1: Download ZIP
const downloadRes = await RNFS.downloadFile({
fromUrl: ZIP_URL,
toFile: LOCAL_ZIP,
}).promise;

if (downloadRes.statusCode === 200) {
// Step 2: Extract
const extractedPath = await unzip(LOCAL_ZIP, EXTRACT_PATH);
await RNFS.unlink(LOCAL_ZIP); // Clean up
console.log('Assets extracted to:', extractedPath);
} else {
console.warn('Failed to download OTA bundle');
}
};
?️ Step 5: Loading Images Dynamically


React Native’s require() doesn’t support dynamic paths. Instead, you use the file:// URI scheme to load images like this:


import React from 'react';
import { Image, StyleSheet } from 'react-native';
import RNFS from 'react-native-fs';

const imagePath = `${RNFS.DocumentDirectoryPath}/ota-bundles/drawable-mdpi/assets_workoutimage_triceps_tricepdips.webp`;

export default function TricepsImage() {
return <Image source={{ uri: `file://${imagePath}` }} style={styles.image} />;
}

const styles = StyleSheet.create({
image: {
width: 120,
height: 120,
resizeMode: 'contain',
},
});

This works across all densities by checking PixelRatio and dynamically selecting the correct drawable-* folder if needed.


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу