Skip to main content

Advanced configuration

Using custom headers
If you need to send custom headers with your download request, you can do in it 2 ways:
  1. Globally using setConfig():
import { setConfig } from '@kesha-antonov/react-native-background-downloader'

setConfig({
headers: {
Authorization: 'Bearer 2we$@$@Ddd223',
}
})

This way, all downloads with have the given headers.

  1. Per download by passing a headers object in the options of createDownloadTask():
import { createDownloadTask, directories } from '@kesha-antonov/react-native-background-downloader'

const task = createDownloadTask({
id: 'file123',
url: 'https://link-to-very.large/file.zip'
destination: `${directories.documents}/file.zip`,
headers: {
Authorization: 'Bearer 2we$@$@Ddd223'
}
}).begin(({ expectedBytes, headers }) => {
console.log(`Going to download ${expectedBytes} bytes!`)
}).progress(({ bytesDownloaded, bytesTotal }) => {
console.log(`Downloaded: ${bytesDownloaded / bytesTotal * 100}%`)
}).done(({ location, bytesDownloaded, bytesTotal }) => {
console.log('Download is done!', { location, bytesDownloaded, bytesTotal })
}).error(({ error, errorCode }) => {
console.log('Download canceled due to error: ', { error, errorCode })
})

task.start()

Headers given in createDownloadTask() are merged with the ones given in setConfig({ headers: { ... } }).

Configuring parallel downloads and network types

You can configure global settings for download behavior using setConfig():

Max Parallel Downloads

Control how many downloads transfer at once. This is useful for managing bandwidth and server load.

import { setConfig } from '@kesha-antonov/react-native-background-downloader'

// Set maximum parallel downloads to 8 (default is 4)
setConfig({
maxParallelDownloads: 8
})

Note: the two platforms apply it at different layers. On iOS it is the download session's maximum simultaneous connections per host. On Android it caps the library's own downloader - the mechanism used on Android 16+, and whenever DownloadManager or a UIDT job can't take the download - while downloads that run through DownloadManager or the JobScheduler are queued by those schedulers instead.

Cellular/WiFi Restrictions

Control whether downloads are allowed over cellular (metered) networks:

import { setConfig } from '@kesha-antonov/react-native-background-downloader'

// Only allow downloads over WiFi (disable cellular data)
setConfig({
allowsCellularAccess: false
})

// Allow downloads over both WiFi and cellular (default)
setConfig({
allowsCellularAccess: true
})

This is a cross-platform setting that works on both iOS and Android:

  • iOS: Sets the allowsCellularAccess property on the NSURLSession configuration
  • Android: Applied on all three download mechanisms - DownloadManager requests (setAllowedOverMetered), the UIDT/JobScheduler jobs used on Android 14+ (the job requires an unmetered network), and the foreground-service fallback used on Android < 14 (gated on a ConnectivityManager unmetered-network callback)

When cellular is disallowed and the device only has a metered connection, the download doesn't fail - it waits until an unmetered network (e.g. WiFi) becomes available, then starts automatically. If the unmetered network is lost mid-download (e.g. WiFi drops and the device falls back to cellular), the download pauses instead of failing and automatically resumes from where it left off once an unmetered network returns. The restriction is kept across pause/resume and app restarts.

Per-download override (Android only): On Android, you can override the global cellular setting for individual downloads using the isAllowedOverMetered option in createDownloadTask():

const task = createDownloadTask({
id: 'file123',
url: 'https://link-to-very.large/file.zip',
destination: `${directories.documents}/file.zip`,
isAllowedOverMetered: true // This download can use cellular even if global setting is false
})
iOS Data Protection (downloading while the device is locked)

On iOS, files protected with NSFileProtectionComplete cannot be written while the device is locked. Since a background download can finish while the screen is locked, the library saves files with completeUntilFirstUserAuthentication by default - writable while locked after the first unlock since boot - and, if a save still can't happen because the device is locked, it stages the bytes and finishes the save (emitting complete) when the device is next unlocked.

You usually don't need to change this. If your app has stricter security requirements you can raise the protection level globally or per task (iOS only - ignored on Android):

import { setConfig, createDownloadTask, directories } from '@kesha-antonov/react-native-background-downloader'

// Global default for all downloads
setConfig({
iosDataProtection: 'completeUntilFirstUserAuthentication', // default
})

// Per-download override
const task = createDownloadTask({
id: 'secret-doc',
url: 'https://example.com/secret.pdf',
destination: `${directories.documents}/secret.pdf`,
iosDataProtection: 'complete', // strongest; note: won't be writable while locked before first unlock
})
ValueNSFileProtection levelNotes
'completeUntilFirstUserAuthentication'NSFileProtectionCompleteUntilFirstUserAuthenticationDefault. Accessible after the first unlock since boot - recommended for background downloads
'complete'NSFileProtectionCompleteStrongest. File is inaccessible whenever the device is locked
'completeUnlessOpen'NSFileProtectionCompleteUnlessOpenAccessible while open, even if the device locks afterward
'none'NSFileProtectionNoneNo protection
Enabling debug logs

The library includes verbose debug logging that can help diagnose download issues. Logging is disabled by default but can be enabled at runtime using setConfig(). Logging works in both debug and production/release builds.

import { setConfig } from '@kesha-antonov/react-native-background-downloader'

// Option 1: Enable native console logging (logs appear in Xcode/Android Studio console)
setConfig({
isLogsEnabled: true
})

// Option 2: Enable logging with a JavaScript callback to capture logs in your app
setConfig({
isLogsEnabled: true,
logCallback: (log) => {
// log.message - The debug message
// log.taskId - Optional task ID associated with the log (iOS only)
console.log('[BackgroundDownloader]', log.message)

// You can also send logs to your analytics/crash reporting service
// crashlytics.log(log.message)
}
})

// Disable logging
setConfig({
isLogsEnabled: false
})

Notes:

  • When isLogsEnabled is true, native debug logs (NSLog on iOS, Log.d/w/e on Android) are printed
  • The logCallback function is called for each native debug log (iOS only sends logs to callback currently)
  • Logs include detailed information about download lifecycle, session management, and errors
  • In production builds, logs are only printed when explicitly enabled via isLogsEnabled
Handling slow-responding URLs

This library automatically includes connection timeout improvements for slow-responding URLs. By default, the following headers are added to all download requests on Android:

  • Connection: keep-alive - Keeps the connection open for better handling
  • Keep-Alive: timeout=600, max=1000 - Sets a 10-minute keep-alive timeout
  • User-Agent: ReactNative-BackgroundDownloader/3.2.6 - Proper user agent for better server compatibility

These headers help prevent downloads from getting stuck in "pending" state when servers take several minutes to respond initially. You can override these headers by providing your own in the headers option.

Handling URLs with many redirects (Android)

Android's DownloadManager has a built-in redirect limit that can cause ERROR_TOO_MANY_REDIRECTS for URLs with multiple redirects (common with podcast URLs, tracking services, CDNs, etc.).

To handle this, you can use the maxRedirects option to pre-resolve redirects before passing the final URL to DownloadManager:

import { Platform } from 'react-native'
import { createDownloadTask, directories } from '@kesha-antonov/react-native-background-downloader'

// Example: Podcast URL with multiple redirects
const task = createDownloadTask({
id: 'podcast-episode',
url: 'https://pdst.fm/e/chrt.fm/track/479722/arttrk.com/p/example.mp3',
destination: `${directories.documents}/episode.mp3`,
maxRedirects: 10, // Follow up to 10 redirects before downloading
}).begin(({ expectedBytes }) => {
console.log(`Going to download ${expectedBytes} bytes!`)
}).progress(({ bytesDownloaded, bytesTotal }) => {
console.log(`Downloaded: ${bytesDownloaded / bytesTotal * 100}%`)
}).done(({ location, bytesDownloaded, bytesTotal }) => {
console.log('Download is done!', { location, bytesDownloaded, bytesTotal })
}).error(({ error, errorCode }) => {
console.log('Download canceled due to error: ', { error, errorCode })

if (errorCode === 1005) { // ERROR_TOO_MANY_REDIRECTS
console.log('Consider increasing maxRedirects or using a different URL')
}
})

task.start()

Notes on maxRedirects:

  • Only available on Android (iOS handles redirects automatically)
  • If not specified or set to 0, no redirect resolution is performed
  • Uses HEAD requests to resolve redirects efficiently
  • Falls back to original URL if redirect resolution fails
  • Respects the same headers and timeouts as the main download
Notification Configuration (Android)

On Android 14+ (API 34), downloads use User-Initiated Data Transfer (UIDT) jobs which require notifications. Due to Android system requirements, notifications cannot be completely disabled when using UIDT jobs. However, you can control their visibility:

  • When showNotificationsEnabled: true - Full notifications with progress, title, and custom texts
  • When showNotificationsEnabled: false (default) - Minimal silent notifications with lowest priority that are barely noticeable

Basic configuration:

import { setConfig } from '@kesha-antonov/react-native-background-downloader'

// Enable notifications and notification grouping with custom texts
setConfig({
showNotificationsEnabled: true, // Show full notifications (default: false - minimal silent notifications)
notificationsGrouping: {
enabled: true, // Enable grouping (default: false)
texts: {
downloadTitle: 'Download',
downloadStarting: 'Starting download...',
downloadProgress: 'Downloading... {progress}%',
downloadPaused: 'Paused',
downloadFinished: 'Download complete',
groupTitle: 'Downloads',
groupText: '{count} downloads in progress',
},
},
})

// Use minimal silent notifications (default behavior)
setConfig({
showNotificationsEnabled: false, // Minimal silent notifications (required by UIDT but barely visible)
})

Cancel button and completion notification (Android 14+):

Two extras are available on top of showNotificationsEnabled. Both are off by default, so enabling notifications alone never adds an alerting notification or a button your app is not ready for:

setConfig({
showNotificationsEnabled: true,
// Adds a Cancel button to the download notification. Tapping it stops the
// download like task.stop() and fires the task's .error() handler with
// errorCode = -1, so handle that in your app before enabling it.
showCancelAction: true,
// Posts a "download complete" notification when a download finishes.
// Tapping it opens the saved file with the system chooser.
// Skipped in 'summaryOnly' grouping mode.
showCompletionNotification: true,
notificationsGrouping: {
enabled: true,
texts: {
downloadCancel: 'Cancel', // Label of the Cancel button
downloadFinished: 'Download complete', // Title of the completion notification
},
},
})

Per-download notification titles are supported too - pass metadata.notificationTitle to override groupName and the default downloadTitle for a single download. See Platform Notes for the full behavior.

Notification grouping modes:

When downloading many files (e.g., thousands of photos), you can use the mode option to control how notifications are displayed:

ModeDescription
'individual'Default. Shows all individual notifications grouped together with a summary
'summaryOnly'Shows only ONE notification with real-time aggregate progress (e.g., "45% - 5 files"). Individual UIDT notifications are collapsed into an invisible group. Ideal for bulk downloads
import { setConfig } from '@kesha-antonov/react-native-background-downloader'

// For bulk downloads (e.g., syncing thousands of photos)
// Use 'summaryOnly' mode to show only ONE notification with aggregate progress
setConfig({
showNotificationsEnabled: true,
notificationsGrouping: {
enabled: true,
mode: 'summaryOnly', // Only show summary notification with progress bar
texts: {
groupTitle: 'Syncing Photos',
groupText: '{count} files downloading',
},
},
})

Example: Batch downloading multiple files with grouped notifications:

import { setConfig, createDownloadTask, directories } from '@kesha-antonov/react-native-background-downloader'

// Configure for bulk downloads with single summary notification
setConfig({
showNotificationsEnabled: true,
notificationsGrouping: {
enabled: true,
mode: 'summaryOnly',
texts: {
groupTitle: 'Photo Sync',
groupText: '{count} photos downloading',
},
},
})

// Download multiple files - they all share ONE notification with aggregate progress
const photos = [
{ id: 'photo-1', url: 'https://example.com/photo1.jpg' },
{ id: 'photo-2', url: 'https://example.com/photo2.jpg' },
{ id: 'photo-3', url: 'https://example.com/photo3.jpg' },
// ... potentially thousands of files
]

const GROUP_ID = 'photo-sync-batch'

for (const photo of photos) {
const task = createDownloadTask({
id: photo.id,
url: photo.url,
destination: `${directories.documents}/${photo.id}.jpg`,
metadata: {
groupId: GROUP_ID, // Required for grouping
groupName: 'Photo Sync', // Displayed in notification title
},
})
.progress(({ bytesDownloaded, bytesTotal }) => {
// Progress tracked per file, notification shows aggregate progress
})
.done(() => {
console.log(`Downloaded ${photo.id}`)
})
.error(({ error }) => {
console.error(`Failed ${photo.id}:`, error)
})

task.start()
}

// User sees: ONE notification showing "45% - 3 files" with progress bar
// instead of 3 separate notifications cluttering the notification shade
// Notification automatically disappears when all downloads complete

Grouping downloads by category:

When notification grouping is enabled, you can group related downloads (e.g., by album, playlist, podcast) by passing groupId and groupName in the task metadata:

import { createDownloadTask, directories } from '@kesha-antonov/react-native-background-downloader'

// Download album songs - they will be grouped under one notification
const task = createDownloadTask({
id: 'song-1',
url: 'https://example.com/albums/summer-hits/track01.mp3',
destination: `${directories.documents}/track01.mp3`,
metadata: {
groupId: 'album-summer-hits', // Unique identifier for the group
groupName: 'Summer Hits 2024', // Display name in notification title
},
})

task.start()

Notification behavior during pause/resume:

When a download is paused on Android 14+:

  • The background UIDT job is cancelled (to prevent downloads continuing in background)
  • A detached "Paused" notification remains visible showing current progress
  • When resumed, a new UIDT job is created and the notification switches to "Downloading" state
  • When stopped, the notification is removed
  • When app is closed, all download notifications are automatically removed

This ensures users always see the download status without unexpected background activity.

Configuration options:

OptionTypeDefaultDescription
showNotificationsEnabledbooleanfalseShow full download notifications. When false, creates minimal silent notifications (UIDT jobs require a notification, but it will be barely visible). This is a top-level config option.
notificationsGrouping.enabledbooleanfalseEnable notification grouping
notificationsGrouping.mode'individual' | 'summaryOnly''individual'Notification display mode. Use 'summaryOnly' for bulk downloads to show only ONE notification with real-time aggregate progress
notificationsGrouping.textsobjectSee belowCustomizable notification texts

Notification texts (notificationsGrouping.texts):

KeyDefaultPlaceholdersDescription
downloadTitle'Download'Title for individual download notifications
downloadStarting'Starting download...'Text when download is starting
downloadProgress'Downloading... {progress}%'{progress}Progress text with current percentage (0-100)
downloadPaused'Paused'Text when download is paused
downloadFinished'Download complete'Text when download is finished
groupTitle'Downloads'Title for group summary notification
groupText'{count} download(s) in progress'{count}Group summary text with active downloads count

Notes:

  • Notifications cannot be completely disabled on Android 14+ due to UIDT requirements
  • When showNotificationsEnabled: false, notifications are created with minimal visibility (lowest priority, empty content)
  • Paused downloads show a non-ongoing notification (can be swiped away by user)
  • Active downloads show an ongoing notification (cannot be swiped away)
  • This feature only affects Android 14+ (API 34) where UIDT jobs are used
  • On older Android versions, the standard DownloadManager notifications are shown
  • iOS uses system download notifications and doesn't support custom grouping
  • Use mode: 'summaryOnly' when downloading many files to prevent notification spam - shows ONE notification with aggregate progress bar that updates in real-time