PowerSync React Native Background Syncing

Fahad RizwanFahad Rizwan
3 min read

To ensure your app can sync changes in the background using PowerSync, you'll need a few essential dependencies provided by Expo:

  • expo-background-fetch (for SDKs below 53) or expo-background-task (for SDK 53 and above)

  • expo-task-manager

These libraries allow you to run background tasks periodically, even when your app is not active.

To install them, run the following command:

bunx expo install expo-background-task expo-task-manager

Platform differences

Android

On Android, the WorkManager API allows specifying a minimum interval for a task to run (minimum 15 minutes). The task will execute sometime after the interval has passed, provided the specified conditions are met.

iOS

On iOS, the BGTaskcheduler API decides the best time to launch your background task. The system will consider the battery level, the network availability, and the user's usage patterns to determine when to run the task. You can still specify a minimum interval for the task to run, but the system may choose to run the task at a later time.

Then we can create a separate file called BackgroundSyncTask.ts, where we will define our task.

TaskManager.defineTask(BACKGROUND_SYNC_TASK, async () => {


  try {
    // Step 1: Validate your tokens first for powersync
    // Step 2: Connect to powersync instance
    const connector = new Connector(token);
    await powersync.connect(connector, {
      params,
    });

    //Step 3: Perform any logic you want to here, powersync will automatically handle syncing and uploading
    drizzleDB.insert().into(anyTable)
    //You can also register a listener here as well
    await new Promise((resolve) => {
    const unregister = powersyncAuth.registerListener({
      statusChanged: (status) => {
        const hasSynced = Boolean(
          status.lastSyncedAt
        );

        const downloading = status.dataFlow?.downloading || false;

        const uploading = status.dataFlow?.uploading || false;

        console.log(
          '[PowerSync] Status changed:',
          hasSynced ? 'βœ… Synced' : '⏳ Not yet synced',
          downloading ? 'πŸ“₯ Downloading' : 'βœ… Not downloading',
          uploading ? 'πŸ“€ Uploading' : 'βœ… Not uploading'
        );

        // You can track download progress here if needed
        // e.g., status.dataFlow?.downloadProgress

        // Resolve only when initial sync is complete
        if (hasSynced && !uploading) {
          console.log('[PowerSync] Sync complete βœ…');
          resolve();
          unregister();
        }
      },
    });
  });

    return BackgroundTask.BackgroundTaskResult.Success;
  } catch (error) {
    console.error('❌ Background sync task failed:', error);
    return BackgroundTask.BackgroundTaskResult.Failed;
  }
});

PowerSync automatically syncs the new changes, no need to invoke its uploadData function

HEADS UP: if you are stuck at this error

[PowerSyncStream]', 'Could not apply checkpoint due to local data. Waiting for in-progress upload before retrying.'

In your uploadData function, if you're using the native fetch() API, keep in mind that it may not work reliably in the background. To improve stability, consider switching to a library like axios, which offers better handling of timeouts, retries, and error states.

After ensuring your upload logic is solid, enhance your background task by adding checks like:

  • βœ… Is the task registered?

  • βœ… Is the device connected to the network?

Once that's done, make sure to register your task at the top level of your app β€” for example, in your index.ts or main layout file:

async function registerBackgroundTaskAsync() {
  return BackgroundTask.registerTaskAsync(BACKGROUND_TASK_IDENTIFIER);
}

And that’s it β€” you now have a working background sync task using PowerSync in your React Native + Expo app. πŸŽ‰ This setup ensures your app remains consistent and up-to-date, even when running in the background.

To test and debug the task on your android device you can follow these instructions on expo docs

0
Subscribe to my newsletter

Read articles from Fahad Rizwan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Fahad Rizwan
Fahad Rizwan