π Setting Up Background Downloads, ZIP Extraction & Notifications in React Native
π¦ 1. Create a React Native Project
If you donβt already have a project:
npx react-native init MyApp
π 2. Install Required Libraries
Weβll use the following libraries:
-
@kesha-antonov/react-native-background-downloaderβ Background downloads -
react-native-zip-archiveβ Unzipping files -
react-native-notificationsβ Local notifications -
react-native-fsβ File system operations
Install via npm:
npm install @kesha-antonov/react-native-background-downloader react-native-zip-archive react-native-notifications react-native-fs
Or via yarn:
yarn add @kesha-antonov/react-native-background-downloader react-native-zip-archive react-native-notifications react-native-fs
βοΈ 3. Configuration
Make sure to follow platform-specific setup:
β Android
- Add required permissions in
AndroidManifest.xml - Enable background services if needed
π iOS
- Configure notification permissions
- Enable background modes (Background Fetch / Processing)
π§ 4. Full Implementation Example
Below is a complete React Native component handling:
- Background download
- ZIP extraction
- Progress tracking
- Notifications
import React, { useState, useEffect } from 'react';
import { Layout, Text, normalize } from 'component';
import { CustomThemeProps } from 'config/theme';
import { useThemeToggle } from 'hooks';
import styled from 'styled-components/native';
import I18n from 'i18';
import { View } from 'react-native';
import * as Progress from 'react-native-progress';
import { Notifications } from 'react-native-notifications';
import RNBackgroundDownloader from '@kesha-antonov/react-native-background-downloader';
import { unzip } from 'react-native-zip-archive';
import RNFS from 'react-native-fs';
const ToggleButton = styled.TouchableOpacity`
background-color: ${({ theme }: CustomThemeProps) => theme.BUTTON_BG_COLOR};
`;
const ToggleButtonText = styled(Text)<{ FontSize: number }>`
color: ${({ theme }: CustomThemeProps) => theme.BUTTON_TEXT_COLOR};
font-size: ${(prop: { FontSize: number }) => `${normalize(prop.FontSize)}px`};
`;
const TextDesc = styled(Text)<{ color?: string }>`
margin: ${normalize(2)}px;
color: ${({ theme, color }: CustomThemeProps & { color?: string }) =>
color ? color : theme.BUTTON_TEXT_COLOR};
padding: 12px;
font-weight: bold;
background-color: ${({ theme }: CustomThemeProps) => theme.BUTTON_BG_COLOR};
margin: 10px;
`;
const Login: React.FC = () => {
const { toggleTheme, ThemeName } = useThemeToggle();
const [ProgressLoad, SetProgressLoad] = useState<number>(0);
useEffect(() => {
Notifications.registerRemoteNotifications();
checkExistingDownloads();
}, []);
const checkExistingDownloads = async () => {
const existingTasks = await RNBackgroundDownloader.checkForExistingDownloads();
const existingTask = existingTasks.find(task => task.id === 'file_11111');
if (existingTask) {
existingTask
.progress(({ bytesDownloaded, bytesTotal }) => {
SetProgressLoad(bytesDownloaded / bytesTotal);
})
.done(() => console.log('Download completed'))
.error(error => console.log(error));
}
};
const sendLocalNotification = () => {
Notifications.postLocalNotification({
body: 'File Uploaded!',
title: 'Download Completed π',
sound: 'chime.aiff',
silent: false,
});
};
const collectFilePaths = async (dirPath: string, filePaths: string[] = []) => {
const contents = await RNFS.readDir(dirPath);
for (const item of contents) {
if (item.isDirectory()) {
await collectFilePaths(item.path, filePaths);
} else {
filePaths.push(item.path);
}
}
return filePaths;
};
const downloadFile = (url: string) => {
return new Promise<string>((resolve, reject) => {
const destination = `${RNBackgroundDownloader.directories.documents}/file_11111.zip`;
RNBackgroundDownloader.download({
id: 'file_11111',
url,
destination,
})
.progress(({ bytesDownloaded, bytesTotal }) => {
SetProgressLoad(bytesDownloaded / bytesTotal);
})
.done(() => resolve(destination))
.error(reject);
});
};
const Download_and_Unzip = async () => {
try {
const url = 'http://localhost:5005/download';
const filePath = await downloadFile(url);
const unzipPath = await unzip(
filePath,
`${RNBackgroundDownloader.directories.documents}/file_${Date.now()}`
);
const files = await collectFilePaths(unzipPath);
console.log(files);
sendLocalNotification();
} catch (err) {
console.log(err);
}
};
return (
<Layout style={{ flex: 1 }}>
<ToggleButton onPress={toggleTheme}>
<ToggleButtonText FontSize={18}>
{I18n.t('THEMEIS')} : {ThemeName}
</ToggleButtonText>
</ToggleButton>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
{ProgressLoad > 0 && (
<>
<Text>{`Progress: ${(ProgressLoad * 100).toFixed(2)}%`}</Text>
<Progress.Bar progress={ProgressLoad} width={350} />
</>
)}
<TextDesc onPress={Download_and_Unzip}>
Download & Extract
</TextDesc>
</View>
</Layout>
);
};
export default Login;
π How It Works
π₯ Background Downloads
- Uses
react-native-background-downloader - Supports resume + persistence across app restarts
π¦ ZIP Extraction
- Uses
react-native-zip-archive - Extracts files after download completes
π File Handling
- Uses
react-native-fs - Recursively collects extracted file paths
π Notifications
- Uses
react-native-notifications - Alerts user when download is complete
β Conclusion
This setup enables you to:
- Download files in the background
- Handle large ZIP files efficiently
- Extract and manage content
- Notify users in real-time
Perfect for apps dealing with:
- Offline content
- Media downloads
- Document handling (PDFs, SDS, etc.)
Top comments (0)