|
| 1 | +# Background synchronization with PowerSync on Android |
| 2 | + |
| 3 | +The PowerSync SDK supports background synchronization (i.e., synchronization clients active without |
| 4 | +a visible UI). |
| 5 | +To use background synchronization, make sure that: |
| 6 | + |
| 7 | +1. You only use a single instance of your `PowerSyncDatabase`. Using multiple instances means that |
| 8 | + multiple write connections are active, which can lead to "database is locked" issues, wasted |
| 9 | + resource due to multiple sync clients, and `watch()`ed queries not updating due to missing update |
| 10 | + notifications. |
| 11 | +2. You don't use separate processes for the UI and the background service. |
| 12 | + |
| 13 | +These limitations are not inherent architectural issues, but sharing databases across processes is |
| 14 | +not currently supported in the Android SDK. Please reach out if you need that feature! |
| 15 | + |
| 16 | +PowerSync works by creating a long-lived connection to a synchronization service that pushes |
| 17 | +database changes. This means that PowerSync works best with background services that can stay active |
| 18 | +for longer periods of time. |
| 19 | +At the same time, PowerSync is able to handle interruptions - so you can also connect your database |
| 20 | +to the sync service on a short-lived task like e.g. WorkManager. PowerSync will try to download as |
| 21 | +many operations as possible, and automatically picks up work from where it was previously stopped. |
| 22 | + |
| 23 | +## Case study: Foreground services |
| 24 | + |
| 25 | +The `androidBackgroundSync/` folder of the `supabase-todolist` demo contains a working example that |
| 26 | +keeps synchronization active without a listening UI. |
| 27 | +While it uses foreground services on Android, other APIs that run work in the same process would |
| 28 | +work too. |
| 29 | + |
| 30 | +To set up this type of sync in your app, follow these steps: |
| 31 | + |
| 32 | +1. Set up your app for background sync. In the example, we declare a new service with |
| 33 | + `android:foregroundServiceType="dataSync"` and add the `FOREGROUND_SERVICE`, |
| 34 | + `FOREGROUND_SERVICE_DATA_SYNC` and `POST_NOTIFICATIONS` permissions. |
| 35 | +2. Adapt an architecture that lets you share a PowerSync database between your compose UI and these |
| 36 | + background services. For Kotlin multiplatform support, our example uses Koin. If Android is your |
| 37 | + only target, you may want to consider Dagger/Hilt instead. As long as you ensure only a single |
| 38 | + instance of the PowerSync database is created, all is good! |
| 39 | +3. Start the service at an appropriate time. In the `MainActivity` of the background sync example, |
| 40 | + we wait for the user to be logged in and then start the foreground service. |
| 41 | +4. In the service, obtain an instance of the database in `onStartCommand` and call |
| 42 | + `database.connect` with your backend connector. If you want the synchronization to be tied to the |
| 43 | + service's lifecycle, call `database.disconnect()` when the service stops. |
| 44 | + |
| 45 | +With those steps, PowerSync will keep synchronizing your database in the backend. You can try this |
| 46 | +out in the example app by: |
| 47 | + |
| 48 | +1. Starting it. |
| 49 | +2. Closing the app by removing the activity from the recently used tasks. |
| 50 | +3. Changing an entry in the database. |
| 51 | +4. Activating airplane mode before opening the app again. |
| 52 | +5. Despite no internet access while the app is open again, the row should be updated in the client |
| 53 | + too! |
| 54 | + |
| 55 | +While this example uses foreground services (because it appears to be the only Android API that |
| 56 | +allows us to keep long-running connections active), adopting a different pattern of e.g. using |
| 57 | +Work Manager to schedule a single sync iteration regularly would also work with a similar pattern. |
0 commit comments