Applications often need to sync data when they’re not in active use. This document explains background syncing implementations with PowerSync.
Background syncing has been tested in:
These examples can be adapted for other frameworks like React Native. For implementation questions or assistance, chat to us on Discord.
Flutter Implementation Guide
Prerequisites
- Complete the workmanager platform setup
- Review the Supabase To-Do List Demo for context
In main.dart
:
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:
// 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);
- 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.
- Run a write (in the case of this demo app, we create a ‘todo list’)
- Make sure to run
currentConnector.uploadData(db);
so that the local write is uploaded to the remote database.
Testing
Add a test button:
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,
},
);
},
),
Press the button, background the app, wait 10 seconds, then verify new records in the remote database.
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 into workmanager.
- While testing we were not able to get iOS background fetching to work, however this is most likely an
issue with the package.
Responses are generated using AI and may contain mistakes.