Skip to main content

Working with Background Tasks

1. Using Task Manager

Example: Registering a Background Task

import * as TaskManager from 'expo-task-manager';

const BACKGROUND_TASK_NAME = 'my-background-task';

TaskManager.registerTaskAsync(BACKGROUND_TASK_NAME, {
  with: {
    periodic: {
      interval: 60 * 1000, // Run every minute
    },
  },
});

export default function BackgroundTask() {
  return null;
}
Property Description Values
name Unique identifier for the task string
with.periodic.interval How often to run the task (in milliseconds) number
with.ios iOS-specific configuration options object
with.android Android-specific configuration options object
Note: Background tasks are subject to OS limitations and may not run at exact intervals.
Warning: Ensure your task completes within the allowed time to avoid termination.

2. Defining Background Tasks

Property Description Values
taskName Unique identifier for the background task 'my-background-task'
executionTimeout Maximum time (in ms) the task can run before being terminated 30000
isAvailable Function to check if the task can be executed () => true

Example: Define a background task

import * as TaskManager from 'expo-task-manager';

const TASK_NAME = 'my-background-task';

TaskManager.defineTask(TASK_NAME, async ({ data, error, executionInfo }) => {
  if (error) {
    console.error('Background task error:', error);
    return;
  }

  // Your background logic here
  console.log('Executing background task:', data);
});
Note: Background tasks must be defined before they can be registered or scheduled.
Warning: Background tasks are subject to system limitations and may not execute immediately.

3. Registering Tasks

Example: Basic Task Registration

import * as TaskManager from 'expo-task-manager';

const TASK_NAME = 'my-background-task';

TaskManager.registerTaskAsync(TASK_NAME, {
  with: {
    interval: 60 * 1000, // Run every minute
    repeat: true,
  },
});
Property Description Values
name Unique identifier for the task string
with Configuration options for task execution object
with.interval How often to run the task (in milliseconds) number
with.repeat Whether to repeat the task boolean
Note: Background tasks must be registered before they can be executed. The task name should be unique across your app.

4. Unregistering Tasks

Unregistering background tasks is essential to prevent unnecessary resource consumption and ensure clean task management. Expo provides methods to unregister tasks either by their ID or by type.

Method Description Notes
TaskManager.unregisterTaskAsync(taskId) Unregisters a specific task by its ID Must be called with the exact task ID as registered
TaskManager.unregisterAllTasksAsync() Unregisters all currently registered tasks Useful for cleaning up before app shutdown or reset

Example: Unregistering a Specific Task

import * as TaskManager from 'expo-task-manager';

const taskId = 'my-background-task';

await TaskManager.unregisterTaskAsync(taskId);
console.log('Task unregistered');

Example: Unregister All Tasks

import * as TaskManager from 'expo-task-manager';

await TaskManager.unregisterAllTasksAsync();
console.log('All tasks unregistered');

5. Using Background Fetch

Property Description Default Notes
backgroundFetch Enables background fetch capability false Set to true to enable background fetch
minInterval Minimum interval in seconds between fetches 300 Minimum is 300 seconds (5 minutes)

Example: Configure Background Fetch

{
  "expo": {
    "backgroundFetch": true,
    "minInterval": 600
  }
}
Note: Background fetch is subject to OS-level limitations and may not run at the specified interval.
Warning: Ensure your app handles fetch failures gracefully to maintain user experience.

6. Implementing Location Tasks

Property Description Values
taskName Unique identifier for the background task 'location-task'
interval How often the task runs (in milliseconds) 30000
accuracy Accuracy level of location data 10

Example: Registering a Location Task

import * as TaskManager from 'expo-task-manager';

const LOCATION_TASK_NAME = 'background-location-task';

TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data, error }) => {
  if (error) {
    console.error(error);
    return;
  }
  console.log('Received data:', data);
});

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Background location task registered</Text>
    </View>
  );
}
Note: Ensure you have the necessary permissions in your app's manifest or configuration files.
Warning: Background tasks may be limited by device battery optimization settings.

7. Using Geofencing

Property Description Values
region Defines the geographic area to monitor { latitude: number, longitude: number, radius: number }
onEnter Callback when entering the region () => void
onExit Callback when exiting the region () => void

Example: Setting up a Geofence

import * as Location from &#x27;expo-location&#x27;;

const region = {
  latitude: 37.7849,
  longitude: -122.409,
  radius: 100
};

const handleEnter = () => {
  console.log("Entered geofenced area");
};

const handleExit = () => {
  console.log("Exited geofenced area");
};

Location.watchPositionAsync(
  { accuracy: Location.Accuracy.High },
  (position) => {
    // Check if position is within region
    const distance = calculateDistance(
      position.coords.latitude,
      position.coords.longitude,
      region.latitude,
      region.longitude
    );
    if (distance <= region.radius) {
      handleEnter();
    } else {
      handleExit();
    }
  }
);
Note: Geofencing requires background location permissions and may have battery implications.
Warning: Accuracy of geofencing depends on device capabilities and may not be precise in all environments.

8. Handling Task Execution

Property Description Values
taskName Name of the background task to execute string
executionTime Maximum time the task can run (in seconds) number
priority Priority level of the task execution low | normal | high

Example: Scheduling a Background Task

import * as TaskManager from &#x27;expo-task-manager&#x27;;

const taskName = &#x27;my-background-task&#x27;;
const executionTime = 30;

TaskManager.registerTaskAsync(taskName, {
  executionTime,
  priority: &#x27;normal&#x27;
});
Note: Background tasks must be registered before they can be executed. Ensure the task name is unique and matches between registration and execution.
Warning: Tasks with high priority may impact device performance or battery life. Use sparingly and only when necessary.

9. Checking Task Status

Property Description Values
taskId Unique identifier for the task string
status Current status of the task 'active', 'pending', 'finished', 'failed'
startTime Timestamp when the task started Date
endTime Timestamp when the task ended Date

Example: Checking Task Status

import * as TaskManager from 'expo-task-manager';

const taskId = 'my-background-task';
const taskStatus = await TaskManager.getTaskStatusAsync(taskId);

console.log('Task Status:', taskStatus);

10. Managing Battery Optimization (Android)

Property Description Default Notes
backgroundTask Identifier for the background task null Used to uniquely identify the background task
taskName Name of the background task null Used to identify and manage the task in logs or UI
taskType Type of background task (e.g., periodic, one-time) periodic Defines how often the task runs

Example: Registering a Background Task

import * as TaskManager from &#x27;expo-task-manager&#x27;;

const BACKGROUND_TASK_NAME = &#x27;my-background-task&#x27;;

TaskManager.registerTaskAsync(BACKGROUND_TASK_NAME, {
  with: {
    taskName: &#x27;my-background-task&#x27;,
    taskType: TaskManager.TaskType.PERIODIC,
  },
});

export default function App() {
  return <View style={styles.container}></View>;
}
Note: On Android, background tasks may be subject to battery optimization restrictions. Ensure your app is configured to allow background execution.
Warning: Battery optimization can cause background tasks to be suspended or delayed. Users may need to manually disable battery optimization for your app in the device settings.

11. Configuring Minimum Interval

Property Values Description
minimumInterval 1000 Minimum interval in milliseconds between background task executions

Example: Setting Minimum Interval

import * as TaskManager from 'expo-task-manager';

TaskManager.defineTask('my-background-task', async () => {
  // Task logic here
});

// Configure minimum interval to 5 seconds
TaskManager.configure({
  minimumInterval: 5000,
});

12. Handling Task Errors

Error Type Description Handling Strategy
TaskError Generic error thrown when a background task fails Use try...catch around task execution to handle gracefully
TaskTimeoutError Thrown when a task exceeds its timeout limit (default 30 seconds) Implement custom timeout logic or increase taskTimeout in config
TaskCancellationError Thrown when a task is cancelled before completion Check isCancelled() or use AbortController to manage cancellation

Example: Catching Task Errors

import { TaskManager } from 'expo-task-manager';

TaskManager.defineTask('my-background-task', async () => {
  try {
    await performBackgroundWork();
  } catch (error) {
    if (error.name === 'TaskTimeoutError') {
      console.error('Task timed out:', error);
    } else if (error.name === 'TaskCancellationError') {
      console.log('Task was cancelled');
    } else {
      console.error('Unexpected task error:', error);
    }
  }
});
Note: Errors in background tasks do not crash the app but are logged to the console. Ensure proper error handling to prevent silent failures.

Was this article helpful?