PowerSync Attachments Helper for Dart/Flutter
PowerSync Attachments Helper is a package that assists in keeping files in sync between local and remote storage.
Warning
This package will eventually be replaced by a new attachments helper library in the core PowerSync package, available through:
package:powersync_core/attachments/attachments.dart
The powersync_core/attachments library is in alpha and brings improved APIs and functionality that is more in line with our other SDKs, such as the ability to write your own local storage implementation.
Check out the docs here to get started.
While the powersync_attachments_helper package will still get bug fixes if you need them,
new features will only be developed on powersync_core/attachments.
Features
- Handles syncing uploads, downloads and deletes between local and remote storage.
Getting started
import 'dart:async';
import 'package:powersync_attachments_helper/powersync_attachments_helper.dart';
import 'package:powersync_core/powersync_core.dart';
// Set up schema with an id field that can be used in watchIds().
// In this case it is photo_id
const schema = Schema([
Table('users', [Column.text('name'), Column.text('photo_id')])
]);
// Assume PowerSync database is initialized elsewhere
late PowerSyncDatabase db;
// Assume remote storage is implemented elsewhere
late AbstractRemoteStorageAdapter remoteStorage;
late PhotoAttachmentQueue attachmentQueue;
class PhotoAttachmentQueue extends AbstractAttachmentQueue {
PhotoAttachmentQueue(db, remoteStorage)
: super(db: db, remoteStorage: remoteStorage);
// This will create an item on the attachment queue to UPLOAD an image
// to remote storage
@override
Future<Attachment> saveFile(String fileId, int size, {mediaType = 'image/jpeg'}) async {
String filename = '$fileId.jpg';
Attachment photoAttachment = Attachment(
id: fileId,
filename: filename,
state: AttachmentState.queuedUpload.index,
mediaType: mediaType,
localUri: getLocalFilePathSuffix(filename),
size: size,
);
return attachmentsService.saveAttachment(photoAttachment);
}
// This will create an item on the attachment queue to DELETE a file
// in local and remote storage
@override
Future<Attachment> deleteFile(String fileId) async {
String filename = '$fileId.jpg';
Attachment photoAttachment = Attachment(
id: fileId,
filename: filename,
state: AttachmentState.queuedDelete.index);
return attachmentsService.saveAttachment(photoAttachment);
}
// This watcher will handle adding items to the queue based on
// a users table element receiving a photoId
@override
StreamSubscription<void> watchIds({String fileExtension = 'jpg'}) {
return db.watch('''
SELECT photo_id FROM users
WHERE photo_id IS NOT NULL
''').map((results) {
return results.map((row) => row['photo_id'] as String).toList();
}).listen((ids) async {
List<String> idsInQueue = await attachmentsService.getAttachmentIds();
List<String> relevantIds =
ids.where((element) => !idsInQueue.contains(element)).toList();
syncingService.processIds(relevantIds, fileExtension);
});
}
}
// Use this in your main.dart to setup and start the queue
initializeAttachmentQueue(PowerSyncDatabase db) async {
attachmentQueue = PhotoAttachmentQueue(db, remoteStorage);
await attachmentQueue.init();
}
Libraries
- powersync_attachments_helper
- Attachment Helper SDK.