React Native Example
Our React Native To-Do List demo app showcases how to sync attachments (such as photos) using the @powersync/attachments library, the PowerSync Service, and Supabase. In this example, we are syncing photos, however other media types, such as PDFs, are also supported. The library and this example implementation can be used as a reference for implementing similar functionality for a Postgres backend without Supabase.The below assumes you have completed the steps outlined in the To-Do List app Readme. This includes installing and running the PowerSync React Native SDK; setting up a Supabase project; setting up a PowerSync instance and connecting it with Supabase.
Configure Storage in Supabase
In this demo app, Supabase Storage is used to store and serve attachments.- To configure Supabase Storage for your app, navigate to the Storage section of your Supabase project and create a new bucket:

- Give the storage bucket a name, such as media, and hit “Save”.

- Next, configure a policy for this bucket. For the purpose of this demo, we will allow all user operations on the media bucket.
- Create a new policy for the media bucket:


- Give the new policy a name, and allow SELECT, INSERT, UPDATE, and DELETE.

- Proceed to review and save the policy.
supabaseBucket
key:



Implementation Details
The @powersync/attachments library is used in conjunction with the PowerSync Service to sync photos. Refer to the library’s README for an overview of the main components. In summary, they are:AttachmentRecord
to store the metadata of attachments.AttachmentState
to track the sync state of anAttachmentRecord
.AbstractAttachmentQueue
class to manage and syncAttachmentRecord
s:- Track and sync attachment metadata.
- Watch for changes and handle CRUD operations on
AttachmentRecord
s. - Store attachment data on the user’s local storage, using file URIs on the device.
- CameraWidget uses
expo-camera
to allow users to capture a photo. - The photo is stored on the user’s local storage.
- See the savePhoto() method.
- The app includes a basic prompt for the user to grant permission to use the device’s camera.
- A
photo_id
was added as a column to thetodos
table to link a photo to a to-do item. - A local-only
attachments
table is instantiated to store the metadata of photos.
AbstractAttachmentQueue
abstract class and:
- Uses a PowerSync query to gather the relevant photo IDs (see
attachmentIds()
) - Creates
AttachmentRecord
s to store photo metadata. (seenewAttachmentRecord()
) - Uses the
savePhoto()
method to save photos into local storage and add them to the sync queue.
How Syncing Works
Refer to this section in the library’s README to learn more about the various sync states and operations.Future Improvements
The following improvements can be considered for this implementation.- An easier way to set up the local-only
attachments
table and related schema. - Better tooling/APIs for retrying/resuming uploads or downloads when transitioning from an offline into an online state.