Skip to main content

Implementing Background Tasks

1. Running Tasks in Background

Example: Using AsyncStorage for Background Data Persistence

import AsyncStorage from '@react-native-async-storage/async-storage';

const storeData = async (key, value) => {
  try {
    await AsyncStorage.setItem(key, JSON.stringify(value));
  } catch (error) {
    console.error('Error storing data:', error);
  }
};

const getData = async (key) => {
  try {
    const value = await AsyncStorage.getItem(key);
    return value ? JSON.parse(value) : null;
  } catch (error) {
    console.error('Error retrieving data:', error);
    return null;
  }
};

// Example usage
storeData('userPreferences', { theme: 'dark', notifications: true });
Task Type Description Platform Support Notes
Background Fetch Periodically fetch data in the background iOS, Android Use BackgroundFetch module for periodic updates
Headless JS Execute JavaScript without UI Android Allows running JS code when app is not in foreground
Push Notifications Trigger background tasks via push iOS, Android Use Firebase Cloud Messaging or similar services
WorkManager (Android) Run tasks on Android with WorkManager Android Part of AndroidX library, handles lifecycle management
Note: Background execution limits vary by platform and OS version. Always test on target devices.
Warning: Excessive background activity can lead to app rejection from app stores.

2. Using Background Fetch

Property Description Default Notes
backgroundFetch Enables background fetch capability false Requires configuration in Info.plist (iOS) or AndroidManifest.xml (Android)
minimumFetchInterval Minimum time (in seconds) between fetch operations 300 Minimum is 300 seconds (5 minutes)
stopOnTerminate Whether to stop background fetch when app is terminated true Set to false to continue fetching in background

Example: Configure Background Fetch

import BackgroundFetch from 'react-native-background-fetch';

BackgroundFetch.configure({
  minimumFetchInterval: 15, // Fetch every 15 seconds
  stopOnTerminate: false,
}, (taskId) => {
  console.log('[BackgroundFetch] Fetch task: ' + taskId);
  // Perform data sync or other background work
  BackgroundFetch.finish(taskId);
});
Note: On iOS, background fetch requires the UIBackgroundModes key in Info.plist with value fetch.
Warning: Background fetch is not guaranteed to run at the specified interval. The OS may adjust based on battery life and network conditions.

3. Implementing Background Geolocation

Property Description Default Notes
enableHighAccuracy Enables high accuracy mode for location true May impact battery life
distanceFilter Minimum distance (meters) to travel before updating location 10 Set to 0 for updates on every move
interval How often to fetch location (ms) 10000 Minimum 5000ms for battery efficiency
fastestInterval Fastest interval to fetch location (ms) 5000 Must be less than or equal to interval
stationaryRadius Distance (meters) to consider device as stationary 20 Used to stop frequent updates when idle
stopOnTerminate Stop background task when app is terminated false Set to true if you want it to stop
startOnBoot Start background task on device boot false Requires ACCESS_FINE_LOCATION permission

Example: Configure Background Geolocation

import Geolocation from '@react-native-community/geolocation';

Geolocation.configure({
  enableHighAccuracy: true,
  distanceFilter: 10,
  interval: 10000,
  fastestInterval: 5000,
  stationaryRadius: 20,
  stopOnTerminate: false,
  startOnBoot: true
});

Geolocation.startBackgroundTask();

Example: Handle Location Updates

Geolocation.watchPosition(
  (location) => {
    console.log('Location:', location.coords);
  },
  (error) => {
    console.log('Error:', error);
  },
  {
    enableHighAccuracy: true,
    distanceFilter: 10
  }
);
Note: On Android, you must request ACCESS_FINE_LOCATION and ACCESS_BACKGROUND_LOCATION permissions for background geolocation to work.
Warning: Background location tracking can drain battery quickly. Always set distanceFilter and interval to reasonable values.

4. Scheduling Background Jobs

Property Description Values
jobId Unique identifier for the background job string
interval Time interval in milliseconds to repeat the job number
data Arbitrary data to pass to the job function object
repeat Whether to repeat the job true or false

Example: Scheduling a Background Job

import BackgroundFetch from 'react-native-background-fetch';

const jobConfig = {
  jobId: 'my-background-job',
  interval: 300000, // 5 minutes
  data: { message: 'Hello from background' },
  repeat: true
};

BackgroundFetch.scheduleJob(jobConfig);
Note: Ensure that the background fetch permission is granted by the user for jobs to run.
Warning: Background jobs may be throttled or paused by the OS to preserve battery life.

5. Handling Background Notifications

Property Description Values
notification Notification object received in background { title: string, body: string, data?: object }
action Action taken by user 'received' | 'dismissed' | 'pressed'

Example: Handling Background Notification

import { Notifications } from 'expo-notifications';

Notifications.setNotificationHandler({
  handleNotification: async (notification) => {
    return {
      shouldShowAlert: true,
      shouldPlaySound: true,
      shouldSetBadge: false
    };
  }
});

// Listen for notifications while app is in background
Notifications.addNotificationReceivedListener((notification) => {
  console.log('Background notification received:', notification);
});

Notifications.addNotificationResponseReceivedListener((response) => {
  console.log('User pressed notification:', response);
});
Note: Background notifications require proper permissions and configuration in app.json.

Key Points

  • Use Notifications.addNotificationReceivedListener to handle notifications when app is in background
  • Use Notifications.addNotificationResponseReceivedListener to handle user interaction with notifications
  • Configure notification permissions in app.json for iOS and Android

6. Using Headless JS

Headless JS allows you to run JavaScript code in the background, even when the app is not in the foreground. It's particularly useful for tasks like syncing data, processing notifications, or performing long-running operations.

Feature Description Notes
Headless JS Enables background execution of JavaScript code in React Native apps. Available on both iOS and Android platforms.
Task Registration Register tasks using AppRegistry.registerHeadlessTask. Must be registered before the app starts.
Task Execution Tasks are executed in a separate JavaScript context. Does not block the main UI thread.

Example: Registering a Headless JS Task

import { AppRegistry } from 'react-native';

const backgroundTask = async (taskData) => {
  // Perform background work here
  console.log('Background task executed:', taskData);
};

AppRegistry.registerHeadlessTask('MyBackgroundTask', () => backgroundTask);

Example: Triggering a Headless JS Task

import { NativeModules } from 'react-native';

const triggerBackgroundTask = () => {
  NativeModules.BackgroundTask.runBackgroundTask({
    taskName: 'MyBackgroundTask',
    data: { message: 'Hello from background!' }
  });
};

triggerBackgroundTask();
Note: On Android, Headless JS tasks are not supported in all versions of React Native. Ensure compatibility with your target version.
Warning: Background tasks may be limited by platform restrictions and battery optimization settings.

7. Implementing Background Audio

Property Description Notes
backgroundAudio Enables audio playback in the background Requires proper permissions and configuration
audioCategory Defines the audio category for playback Options: playback, ambient, soloAmbient
audioMode Configures audio mode for iOS Options: default, ambient, playAndRecord

Example: Setting up Background Audio

import { Audio } from 'expo-av';<br><br>Audio.setAudioModeAsync({<br>  androidMode: 'playback',<br>  iosCategory: 'playback',<br>  staysActiveInBackground: true,<br>});
Note: On iOS, ensure AVAudioSession is configured correctly to allow background audio.
Warning: Background audio may drain battery quickly. Implement proper cleanup to avoid memory leaks.
Platform Support Status Notes
Android Supported Requires FOREGROUND_SERVICE permission
iOS Supported Uses AVAudioSession
Web Limited Background audio not supported natively

8. Managing Battery Optimization

Property Description Values Notes
backgroundTaskId Identifier for the registered background task string Used to manage and cancel tasks
taskName Name of the background task string Used for logging and debugging

Example: Registering a Background Task

import { AppState } from 'react-native';\n\nconst backgroundTaskId = await BackgroundFetch.scheduleTask({\n  taskId: 'com.example.background-task',\n  delay: 30000,\n  periodic: true,\n});
Note: Battery optimization is critical for mobile apps. Use background tasks sparingly to avoid draining the battery.
Warning: Some devices may restrict background execution. Always test on real devices.
Platform Support Notes
Android Good Uses WorkManager for task scheduling
iOS Good Uses Background App Refresh

9. Testing Background Tasks

Example: Testing Background Task with Jest

import { NativeModules } from 'react-native';
import { jest, it, expect } from '@jest/globals';

// Mock the native module
NativeModules.BackgroundTaskManager = {
  startBackgroundTask: jest.fn(),
  stopBackgroundTask: jest.fn(),
};

it('should start and stop background task', () => {
  const taskId = NativeModules.BackgroundTaskManager.startBackgroundTask();
  expect(taskId).toBe(123);
  NativeModules.BackgroundTaskManager.stopBackgroundTask(taskId);
});
Method Description Return Type Notes
startBackgroundTask Starts a new background task number Unique task ID
stopBackgroundTask Stops a background task by ID void Task must be running
Note: Background tasks are limited by platform-specific constraints and may not run indefinitely.
Warning: Testing background tasks requires platform-specific mocking or real device testing.

Testing Considerations

  • Use NativeModules to mock native implementations
  • Test task lifecycle (start, stop)
  • Validate task IDs and return values
  • Ensure proper cleanup after tests

10. Handling Background Limitations

Note: React Native's background task capabilities are limited compared to native mobile development. These limitations are primarily due to platform restrictions and battery optimization measures in iOS and Android.
Task Type Platform Support Limitations Notes
Background Fetch iOS / Android Maximum 15 minutes interval, limited to 30 seconds of execution time Available via BackgroundFetch library on both platforms
Headless JS Android / iOS Only runs when app is in background or terminated, limited to 10 seconds Useful for processing data without UI interaction
Push Notifications iOS / Android Requires permission, limited payload size (2KB on iOS) Can trigger background tasks via PushNotificationIOS
Location Updates iOS / Android Background location updates are restricted to specific accuracy levels Use react-native-geolocation-service for enhanced control
Audio Playback iOS / Android Audio must be played through system audio session (e.g., AVAudioSession) Use react-native-sound or expo-av for playback

Example: Background Fetch Configuration

import BackgroundFetch from 'react-native-background-fetch';

BackgroundFetch.configure({
  stopOnTerminate: false,
  startOnBoot: true,
  enableHeadless: true,
}, async (taskId) => {
  console.log('[js] Received background-fetch event:', taskId);
  // Perform data sync or other operations here
  await fetch('https://api.example.com/data');
  BackgroundFetch.finish(taskId);
});

Example: Push Notification Setup

import PushNotificationIOS from '@react-native-push-notification/ios';

PushNotificationIOS.addEventListener('notification', (notification) => {
  // Handle notification in background
  const data = notification.getData();
  console.log('Received push notification:', data);
});

Platform-Specific Considerations

  • iOS: Background tasks are limited to 10 seconds and must be handled via HeadlessJS or BackgroundFetch.
  • Android: Background tasks can run longer but are subject to Doze mode and App Standby buckets.

Was this article helpful?