expo-background-fetch
provides an API to perform background fetch tasks, allowing you to run specific code periodically in the background to update your app. This module uses TaskManager Native API under the hood.Android Device | Android Emulator | iOS Device | iOS Simulator | Web |
---|---|---|---|---|
expo install expo-background-fetch
. To use it in bare React Native app, follow its installation instructions;expo-background-fetch
.import React from 'react'; import { StyleSheet, Text, View, Button } from 'react-native'; import * as BackgroundFetch from 'expo-background-fetch'; import * as TaskManager from 'expo-task-manager'; const BACKGROUND_FETCH_TASK = 'background-fetch'; // 1. Define the task by providing a name and the function that should be executed // Note: This needs to be called in the global scope (e.g outside of your React components) TaskManager.defineTask(BACKGROUND_FETCH_TASK, async () => { const now = Date.now(); console.log(`Got background fetch call at date: ${new Date(now).toISOString()}`); // Be sure to return the successful result type! return BackgroundFetch.Result.NewData; }); // 2. Register the task at some point in your app by providing the same name, and some configuration options for how the background fetch should behave // Note: This does NOT need to be in the global scope and CAN be used in your React components! async function registerBackgroundFetchAsync() { return BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_TASK, { minimumInterval: 60 * 15, // 15 minutes stopOnTerminate: false, // android only, startOnBoot: true, // android only }); } // 3. (Optional) Unregister tasks by specifying the task name // This will cancel any future background fetch calls that match the given name // Note: This does NOT need to be in the global scope and CAN be used in your React components! async function unregisterBackgroundFetchAsync() { return BackgroundFetch.unregisterTaskAsync(BACKGROUND_FETCH_TASK); } export default function BackgroundFetchScreen() { const [isRegistered, setIsRegistered] = React.useState<boolean>(false); const [status, setStatus] = React.useState<BackgroundFetch.Status | null>(null); React.useEffect(() => { checkStatusAsync(); }, []); const checkStatusAsync = async () => { const status = await BackgroundFetch.getStatusAsync(); const isRegistered = await TaskManager.isTaskRegisteredAsync(BACKGROUND_FETCH_TASK); setStatus(status); setIsRegistered(isRegistered); }; const toggleFetchTask = async () => { if (isRegistered) { await unregisterBackgroundFetchAsync(); } else { await registerBackgroundFetchAsync(); } checkStatusAsync(); }; return ( <View style={styles.screen}> <View style={styles.textContainer}> <Text> Background fetch status:{' '} <Text style={styles.boldText}>{status ? BackgroundFetch.Status[status] : null}</Text> </Text> <Text> Background fetch task name:{' '} <Text style={styles.boldText}> {isRegistered ? BACKGROUND_FETCH_TASK : 'Not registered yet!'} </Text> </Text> </View> <View style={styles.textContainer}></View> <Button title={isRegistered ? 'Unregister BackgroundFetch task' : 'Register BackgroundFetch task'} onPress={toggleFetchTask} /> </View> ); } %%placeholder-start%%%%placeholder-end%%const styles = StyleSheet.create({ screen: { flex: 1, justifyContent: 'center', alignItems: 'center', }, textContainer: { margin: 10, }, boldText: { fontWeight: 'bold', }, });
Instruments
app on macOS to manually trigger background fetches:/Applications/Xcode.app/Contents/Applications/Instruments.app
Time Profiler
Expo Go
appRecord
button in the top left cornerDocument
Menu and select Simulate Background Fetch - Expo Go
:minimumInterval
option of your task to a small number and background your application like so:async function registerBackgroundFetchAsync() { return BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_TASK, { minimumInterval: 1, // task will fire 1 minute after app is backgrounded }); }
BackgroundFetch
API in standalone, detached and bare apps on iOS, your app has to include background mode in the Info.plist file. See background tasks configuration guide for more details.startOnBoot
. It also keeps devices "awake" that are going idle and asleep fast, to improve reliability of the tasks. Because of this both the RECEIVE_BOOT_COMPLETED
and WAKE_LOCK
permissions are added automatically.import * as BackgroundFetch from 'expo-background-fetch';
Gets a status of background fetch.
Promise<BackgroundFetchStatus | null>
Returns a promise which fulfils with one of BackgroundFetchStatus
enum values.
string
) - Name of the task to register. The task needs to be defined first - see TaskManager.defineTask
for more details.BackgroundFetchOptions
) - An object containing the background fetch options.
import * as BackgroundFetch from 'expo-background-fetch'; import * as TaskManager from 'expo-task-manager'; TaskManager.defineTask(YOUR_TASK_NAME, () => { try { const receivedNewData = // do your background fetch here return receivedNewData ? BackgroundFetch.Result.NewData : BackgroundFetch.Result.NoData; } catch (error) { return BackgroundFetch.Result.Failed; } });
Registers background fetch task with given name. Registered tasks are saved in persistent storage and restored once the app is initialized.
number
) - Number of seconds that must elapse before another background fetch can be called.Sets the minimum number of seconds that must elapse before another background fetch can be initiated. This value is advisory only and does not indicate the exact amount of time expected between fetch operations.
This method doesn't take any effect on Android. It is a global value which means that it can
overwrite settings from another application opened through Expo Go.
string
) - Name of the task to unregister.Unregisters background fetch task, so the application will no longer be executing this task.
Name | Type | Description |
---|---|---|
minimumInterval (optional) | number | Inexact interval in seconds between subsequent repeats of the background fetch alarm. The final
interval may differ from the specified one to minimize wakeups and battery usage.
|
startOnBoot (optional) | boolean | (Android only). Whether to restart background fetch events when the device has finished
booting. Defaults to false . |
stopOnTerminate (optional) | boolean | (Android only). Whether to stop receiving background fetch events after user terminates the
app. Defaults to true . |
This return value is to let iOS know what the result of your background fetch was, so the platform can better schedule future background fetches. Also, your app has up to 30 seconds to perform the task, otherwise your app will be terminated and future background fetches may be delayed.
NoData
- There was no new data to download.BackgroundFetchResult.NoData = 1
NewData
- New data was successfully downloaded.BackgroundFetchResult.NewData = 2
Failed
- An attempt to download data was made but that attempt failed.BackgroundFetchResult.Failed = 3
Denied
- The user explicitly disabled background behavior for this app or for the whole system.BackgroundFetchStatus.Denied = 1
Restricted
- Background updates are unavailable and the user cannot enable them again. This status can occur
when, for example, parental controls are in effect for the current user.BackgroundFetchStatus.Restricted = 2
Available
- Background updates are available for the app.BackgroundFetchStatus.Available = 3