react-native-background-actions

repository·master·Indexed 21 days ago

https://github.com/rapsssito/react-native-background-actions

A React Native library for running background tasks indefinitely on Android and iOS. It leverages HeadlessJS on Android and UIApplication background task APIs on iOS. The library includes support for Android foreground service types, required notifications for Android background execution, and expiration event handling for iOS.

Tokens
5.6K
Snippets
13
Records
22
Agent score
76%

What's inside react-native-background-actions

  1. Important platform limitations for Android and iOS

    master

    Before using react-native-background-actions, understand the underlying platform mechanisms and their limitations:

    Android

    • Mechanism: Relies on React Native's HeadlessJS.
    • Behavior: Jobs run even if the app is closed.
    • Android 12+ Restrictions: You cannot launch background tasks from the background.
    • Notifications: A notification is required and will be shown whenever a task is running. It is impossible to start the service without this notification. The notification is only visible on Android.

    iOS

    • Mechanism: Relies on UIApplication beginBackgroundTaskWithName.
    • Limitation: This method will not keep your app in the background forever on its own.
    • Workaround: To achieve long-running background execution on iOS, you must combine this library with other capabilities that keep the app alive, such as audio playback (e.g., using react-native-track-player) or geolocalization.
  2. Configure Android for background actions

    master

    For React Native >= 0.60, you must modify android/app/src/main/AndroidManifest.xml to include necessary permissions and service declarations.

    Basic Permissions

    Add the following to your manifest:

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    Android 14+ Requirements

    Android 14+ requires a foregroundServiceType to be set in the service tag.

    For Data Sync tasks:

    1. Add the permission: <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />.
    2. Add the service tag inside <application>:
    <service 
      android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask"
      android:foregroundServiceType="dataSync"
    />

    For Location tasks: If your use case requires location services, change the foregroundServiceType to location and add these permissions:

    • android.permission.FOREGROUND_SERVICE_LOCATION
    • android.permission.ACCESS_COARSE_LOCATION
    • android.permission.ACCESS_FINE_LOCATION
    <manifest ... >
        <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
        <uses-permission android:name="android.permission.WAKE_LOCK" />
        
        <application ... >
          <service 
            android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask"
            android:foregroundServiceType="dataSync"
          />
        </application>
    </manifest>
  3. Link react-native-background-actions for React Native < 0.60

    master

    If you are using an older version of React Native (< 0.60), you must link the native modules.

    Using CLI:

    react-native link react-native-background-actions

    Manual Linking (iOS):

    1. In Xcode, right-click LibrariesAdd Files to [your project's name].
    2. Navigate to node_modules/react-native-background-actions and add RNBackgroundActions.xcodeproj.
    3. Select your project in Xcode, go to Build PhasesLink Binary With Libraries, and add libRNBackgroundActions.a.

    Manual Linking (Android):

    1. In android/app/src/main/java/[...]/MainApplication.java:
      • Add import com.asterinet.react.bgactions.BackgroundActionsPackage;
      • Add new BackgroundActionsPackage() to the getPackages() method.
    2. In android/settings.gradle:
      include ':react-native-background-actions'
      project(':react-native-background-actions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-actions/android')
    3. In android/app/build.gradle (inside dependencies block):
      compile project(':react-native-background-actions')
  4. Configure iOS for background actions

    master

    For React Native >= 0.60, follow these steps to configure iOS:

    1. Install Pods: Run cd ios && pod install && cd ...
    2. Enable Background Capability: You must activate the background capability in Xcode.
    3. Update Info.plist: To support App Store submission, add the BGTaskSchedulerPermittedIdentifiers key to your Info.plist with your product bundle identifier.

    Note: This configuration is required for the library to function correctly on iOS.

    <key>BGTaskSchedulerPermittedIdentifiers</key>
    <array>
        <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    </array>
  5. Check React Native and Android compatibility

    master

    Ensure your project meets the minimum version requirements for the version of react-native-background-actions you are using. Specifically, note the targetSdkVersion requirement for Android.

    Library VersionAndroid (targetSdkVersion)iOS version
    4.X.X>= 34>= Unknown
    3.X.X>= 31>= Unknown
    2.6.7>= Unknown>= Unknown
  6. Implement Deep Linking for Android Notifications

    master

    To handle incoming links when an Android notification is clicked, follow these steps:

    1. Modify android/app/src/main/AndroidManifest.xml: Add an <intent-filter> to your activity. Ensure android:launchMode="singleTask" is set if not already present.
    <activity
        ... 
        android:launchMode="singleTask">
        <intent-filter android:label="filter_react_native">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="yourSchemeHere" />
        </intent-filter>
    </activity>
    1. Set linkingURI in options: The URI must match the scheme defined in the manifest.
    const options = {
        // ...
        linkingURI: 'yourSchemeHere://chat/jane',
    };
    await BackgroundService.start(task, options);
    1. Listen for the URL in JavaScript: Use React Native's Linking class to handle the event.
    import { Linking } from 'react-native';
    
    Linking.addEventListener('url', handleOpenURL);
    
    function handleOpenURL(evt) {
        console.log(evt.url);
        // Handle the URL
    }
  7. Configure BackgroundService options

    master

    The options object passed to BackgroundService.start() configures the background behavior and notification appearance.

    Main Options

    PropertyTypeDescription
    taskName<string>Task name for identification.
    taskTitle<string>Android Required. Notification title.
    taskDesc<string>Android Required. Notification description.
    taskIcon<taskIconOptions>Android Required. Notification icon.
    color<string>Notification color. Default: "#ffffff".
    linkingURI<string>Link called when notification is clicked. Default: undefined.
    progressBar<taskProgressBarOptions>Notification progress bar.
    foregroundServiceTypeArray<string>Android only. Array of foreground service types. Must match AndroidManifest.xml.
    parameters<any>Parameters passed to the task function.

    taskIconOptions (Android only)

    PropertyTypeDescription
    name<string>Required. Icon name in res/ folder (e.g., ic_launcher).
    type<string>Required. Icon type in res/ folder (e.g., mipmap).
    package<string>Icon package to search. Defaults to app's package.

    taskProgressBarOptions (Android only)

    PropertyTypeDescription
    max<number>Required. Maximum value.
    value<number>Required. Current value.
    indeterminate<boolean>Display progress as indeterminate.
  8. Start and stop background tasks

    master

    Use BackgroundService.start() to initiate a background task with a specific function and configuration options. The task function receives taskDataArguments (defined in the parameters option).

    Important Lifecycle Rules:

    • Do not call .start() twice: Calling it again will stop the previous task and start a new one.
    • Stopping: Use BackgroundService.stop() to end the task. If you call stop() while the app is in the background, no new tasks can be started.
    • Task Constraints: Tasks can perform network requests, timers, etc., but must not touch the UI. Once the task promise resolves, the app enters "paused" mode (unless other tasks are running or the app is in the foreground).
    • iOS Behavior: On iOS, the task runs in the background until .stop() is called.
    import BackgroundService from 'react-native-background-actions';
    
    const veryIntensiveTask = async (taskDataArguments) => {
        const { delay } = taskDataArguments;
        // Use BackgroundService.isRunning() to check if the task should continue
        for (let i = 0; BackgroundService.isRunning(); i++) {
            console.log(i);
            await new Promise((resolve) => setTimeout(resolve, delay));
        }
    };
    
    const options = {
        taskName: 'Example',
        taskTitle: 'ExampleTask title',
        taskDesc: 'ExampleTask description',
        taskIcon: {
            name: 'ic_launcher',
            type: 'mipmap',
        },
        color: '#ff00ff',
        parameters: {
            delay: 1000,
        },
    };
    
    await BackgroundService.start(veryIntensiveTask, options);
    // ... perform work
    await BackgroundService.stop();
  9. Handle iOS Background Expiration Events

    master

    On iOS, you can listen for the 'expiration' event. This allows your application to perform cleanup tasks shortly before the system terminates the background task because its allotted time has expired.

    import BackgroundService from 'react-native-background-actions';
    
    BackgroundService.on('expiration', () => {
        console.log('I am being closed :(');
        // Perform cleanup here
    });
    
    await BackgroundService.start(veryIntensiveTask, options);
  10. Configure Android Foreground Service Types

    master

    For Android 10+ (API 29+), you must specify the foregroundServiceType in your options object. This must match the android:foregroundServiceType declared in your AndroidManifest.xml.

    Supported Values:

    • dataSync (API 29, requires android.permission.FOREGROUND_SERVICE_DATA_SYNC)
    • mediaPlayback (API 29, requires android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK)
    • phoneCall (API 29, requires android.permission.FOREGROUND_SERVICE_PHONE_CALL)
    • location (API 29, requires android.permission.FOREGROUND_SERVICE_LOCATION)
    • connectedDevice (API 29, requires android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE)
    • mediaProjection (API 29, requires android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION)
    • camera (API 30, requires android.permission.FOREGROUND_SERVICE_CAMERA)
    • microphone (API 30, requires android.permission.FOREGROUND_SERVICE_MICROPHONE)
    • health (API 34, requires android.permission.FOREGROUND_SERVICE_HEALTH)
    • remoteMessaging (API 34, requires android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING)
    • systemExempted (API 34, requires android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED)
    • shortService (API 34, requires android.permission.FOREGROUND_SERVICE_SHORT_SERVICE)
    • specialUse (API 34, requires android.permission.FOREGROUND_SERVICE_SPECIAL_USE)

    Note: On versions below API 29, this option is ignored. If a value is not supported by the running Android version, it is silently ignored.

    // Example usage
    const options = {
        // ... other options
        foregroundServiceType: ['location', 'microphone'],
    };