Skip to content

BackgroundFetch

configure

static configure(config: BackgroundFetchConfig, onEvent: (taskId: string) => void, onTimeout?: (taskId: string) => void): Promise<BackgroundFetchStatus>;

Configure the plugin and begin listening for background-fetch events.

Calling configure automatically starts background-fetch (equivalent to calling BackgroundFetch.start immediately after configuration).

The BackgroundFetchConfig.minimumFetchInterval option controls how frequently iOS will wake your app in the background. Android uses JobScheduler (or AlarmManager when forceAlarmManager is true) and supports additional scheduling constraints such as requiredNetworkType, requiresCharging, etc.

Warning

You must call BackgroundFetch.finish within your event callback. Failure to do so will result in the OS throttling future background events for your app.

Basic configuration

const status = await BackgroundFetch.configure({
  minimumFetchInterval: 15,     // <-- iOS: minimum interval in minutes
}, async (taskId) => {
  console.log('[BackgroundFetch] taskId:', taskId);
  // You MUST call finish() when your work is complete.
  BackgroundFetch.finish(taskId);
}, (taskId) => {
  // The OS is about to kill your app — stop all work immediately.
  console.log('[BackgroundFetch] TIMEOUT, taskId:', taskId);
  BackgroundFetch.finish(taskId);
});

console.log('[BackgroundFetch] status:', status);
Android configuration

BackgroundFetch.configure({
  minimumFetchInterval: 15,
  stopOnTerminate: false,     // <-- Continue after app termination
  startOnBoot: true,          // <-- Restart on device reboot
  enableHeadless: true,       // <-- Enable headless task for terminated app
  requiresCharging: false,
  requiresBatteryNotLow: true,
}, async (taskId) => {
  console.log('[BackgroundFetch] taskId:', taskId);
  BackgroundFetch.finish(taskId);
}, (taskId) => {
  BackgroundFetch.finish(taskId);
});

finish

static finish(taskId?: string): void;

Signal to the OS that your background task is complete.

Warning

You must call finish at the end of every background-fetch event callback. Failure to call finish has serious consequences:

  • iOS — The OS may terminate your app and penalise future background-wake frequency.
  • Android — The JobScheduler job will not be considered complete and the OS may throttle or block future executions.

Always call finish as quickly as possible, even when your task encounters an error. For timeout events, call finish immediately without doing any additional work. Example

BackgroundFetch.configure({}, async (taskId) => {
  try {
    await doMyWork();
  } catch (e) {
    console.warn(e);
  } finally {
    // Always call finish, even on error.
    BackgroundFetch.finish(taskId);
  }
}, (taskId) => {
  // Timeout — stop immediately.
  BackgroundFetch.finish(taskId);
});

registerHeadlessTask Android only

static registerHeadlessTask(task: (event: HeadlessEvent) => Promise<void>): void;

Register a function to execute when the app is terminated while background-fetch events remain active.

Requires stopOnTerminate false and enableHeadless true.

How it works

When Android terminates the app, the native module launches a minimal JS context (without the React Native UI) and invokes your headless task function. This allows you to handle background events even when the app is not running.

Registration

Call registerHeadlessTask at your app's entry point (index.js), outside any React component. The registration must happen before the OS attempts to fire a headless event.

Restrictions

  • Do not import modules that depend on the React Native UI runtime (e.g. components, navigation, Redux stores that render UI).
  • Keep the task lightweight — the OS may kill the JS context at any time.
  • Always call BackgroundFetch.finish before the returned Promise resolves. Example
// index.js — register at the app entry point.
import BackgroundFetch, { HeadlessEvent } from 'react-native-background-fetch';

const BackgroundFetchHeadlessTask = async (event: HeadlessEvent) => {
  const taskId = event.taskId;

  if (event.timeout) {
    // OS is about to kill the context — finish immediately.
    BackgroundFetch.finish(taskId);
    return;
  }

  console.log('[BackgroundFetch] Headless event, taskId:', taskId);
  // ... perform lightweight work ...
  BackgroundFetch.finish(taskId);
};

BackgroundFetch.registerHeadlessTask(BackgroundFetchHeadlessTask);

scheduleTask

static scheduleTask(config: TaskConfig): Promise<boolean>;

Schedule a custom one-shot or periodic background task in addition to the default fetch event registered with BackgroundFetch.configure.

Custom tasks fire the same onEvent callback registered in BackgroundFetch.configure, identified by their TaskConfig.taskId. Call BackgroundFetch.finish with that taskId to signal completion, and BackgroundFetch.stop with the taskId to cancel.

iOS

On iOS, custom tasks are registered using the BGProcessingTask API. You must declare each taskId in your app's Info.plist under BGTaskSchedulerPermittedIdentifiers before calling scheduleTask.

Android

Android uses JobScheduler (or AlarmManager when forceAlarmManager is true) and supports all AbstractConfig scheduling constraints. One-shot task

BackgroundFetch.scheduleTask({
  taskId: 'com.foo.customtask',   // <-- unique identifier
  delay: 5000,                    // <-- minimum delay in ms
  forceAlarmManager: true,        // <-- Android: bypass JobScheduler
  stopOnTerminate: false,
});

// The same onEvent callback from configure() will fire with taskId 'com.foo.customtask'.
Periodic task

BackgroundFetch.scheduleTask({
  taskId: 'com.foo.periodic-sync',
  delay: 600000,       // <-- 10 minutes in ms
  periodic: true,      // <-- repeat indefinitely
  requiredNetworkType: BackgroundFetch.NETWORK_TYPE_ANY,  // <-- Android
  requiresNetworkConnectivity: true,  // <-- iOS
});

start

static start(): Promise<BackgroundFetchStatus>;

Start subscribing to background-fetch events.

BackgroundFetch.configure calls start automatically. Use start explicitly only after a previous call to BackgroundFetch.stop. Example

const status = await BackgroundFetch.start();
console.log('[BackgroundFetch] started, status:', status);

status

static status(callback?: (status: BackgroundFetchStatus) => void): Promise<BackgroundFetchStatus>;

Query the current authorization status of the Background Fetch API.

Value Constant Description
0 BackgroundFetchStatus.STATUS_RESTRICTED Background fetch updates are unavailable and the user cannot enable them again (e.g. parental controls).
1 BackgroundFetchStatus.STATUS_DENIED The user explicitly disabled background behavior for this app or the whole system.
2 BackgroundFetchStatus.STATUS_AVAILABLE Background fetch is available and enabled.
Example
const status = await BackgroundFetch.status();
switch (status) {
  case BackgroundFetch.STATUS_RESTRICTED:
    console.log('Background fetch restricted');
    break;
  case BackgroundFetch.STATUS_DENIED:
    console.log('Background fetch denied by user');
    break;
  case BackgroundFetch.STATUS_AVAILABLE:
    console.log('Background fetch available');
    break;
}

stop

static stop(taskId?: string): Promise<boolean>;

Stop subscribing to background-fetch events.

  • If a taskId is provided, only that specific scheduled task is cancelled.
  • If no taskId is provided, all background-fetch and scheduled tasks are cancelled.

Use BackgroundFetch.start to resume after stopping. Example

// Stop all background-fetch events.
await BackgroundFetch.stop();

// Stop a single scheduled task by taskId.
await BackgroundFetch.stop('com.foo.customtask');