> ## Documentation Index
> Fetch the complete documentation index at: https://docs.powersync.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Background Syncing

> Run PowerSync sync operations while your app is in the background to keep local data up to date.

Applications often need to sync data when they're not in active use. This document explains background syncing implementations with PowerSync.

## Platform Support

Background syncing has been tested in:

* **Flutter** - Using [workmanager](https://github.com/fluttercommunity/flutter_workmanager/)
* **React Native & Expo** - Using Expo's `BackgroundTask` API. See our [demo](https://github.com/powersync-ja/powersync-js/tree/main/demos/react-native-supabase-background-sync) and accompanying [blog post](https://www.powersync.com/blog/keep-background-apps-fresh-with-expo-background-tasks-and-powersync).
* **Kotlin - Android** - Implementation details in the [Supabase To-Do List demo](https://github.com/powersync-ja/powersync-kotlin/blob/main/demos/supabase-todolist/docs/BackgroundSync.md)

These examples can be adapted for other platforms/frameworks. For implementation questions or assistance, chat to us on [Discord](https://discord.gg/powersync).

## Flutter Implementation Guide

### Prerequisites

1. Complete the [workmanager platform setup](https://github.com/fluttercommunity/flutter_workmanager/#platform-setup)
2. Review the [Supabase To-Do List Demo](https://github.com/powersync-ja/powersync.dart/tree/main/demos/supabase-todolist) for context

### Configure the Background Task

In `main.dart`:

```dart theme={null}
void main() async {
  // ... existing setup code ...
  
  const simpleTaskKey = "com.domain.myapp.taskId";
  
  // Mandatory if the App is obfuscated or using Flutter 3.1+
  @pragma('vm:entry-point')
  void callbackDispatcher() {
    Workmanager().executeTask((task, inputData) async {
      switch (task) {
        case simpleTaskKey:
          // Initialize PowerSync database and connection
          final currentConnector = await openDatabase();
          db.connect(connector: currentConnector!);
          
          // Perform database operations
          await TodoList.create('New background task item');
          await currentConnector.uploadData(db);
          await TodoList.create('testing1111');
          await currentConnector.uploadData(db);
          // print("$simpleTaskKey was executed. inputData = $inputData");
          break;
      }
      // Close database when done
      await db.close();
      return Future.value(true);
    });
  }

  // Initialize the workmanager with your callback
  Workmanager().initialize(
    callbackDispatcher,
    // Shows notifications during task execution (useful for debugging)
    isInDebugMode: true
  );
  
  // ... rest of your app initialization ...
}
```

Note specifically in the switch statement:

```dart theme={null}
// currentConnector is the connector to the remote DB
// openDatabase sets the db variable to the PowerSync database
final currentConnector = await openDatabase();
// connect PowerSync to the remote database
db.connect(connector: currentConnector!);
// a database write operation
await TodoList.create('Buy new shoes');
// Sync with the remote database
await currentConnector.uploadData(db);
```

1. Since WorkManager executes in a new process, you need to set up the PowerSync local database and connect to the remote database using your connector.
2. Run a write (in the case of this demo app, we create a 'todo list')
3. Make sure to run `currentConnector.uploadData(db);` so that the local write is uploaded to the remote database.

### Testing

Add a test button:

```dart theme={null}
  ElevatedButton(
  title: const Text("Start the Flutter background service"),
     onTap: () async {
        await Workmanager().cancelAll();
        // print("RUN BACKGROUND TASK");
        await Workmanager().registerOneOffTask(
        simpleTaskKey,
        simpleTaskKey,
        initialDelay: Duration(seconds: 10),
        inputData: <String, dynamic>{
        int': 1,
      },
    );
  },
),
```

Click the button, background the app, wait 10 seconds, then verify new records in the remote database.

### Platform Compatibility

#### Android

* Implementation works as expected.

#### iOS

* At the time of last testing this (January 2024), we were only able to get part of this to work using the branch for [this PR](https://github.com/fluttercommunity/flutter_workmanager/pull/511) into workmanager.
* While testing we were not able to get iOS background fetching to work, however this is most likely an
  [issue](https://github.com/fluttercommunity/flutter_workmanager/issues/515) with the package.
