5.8 KiB
| name | description | metadata | ||
|---|---|---|---|---|
| powersync-dart | PowerSync Dart SDK — schema, queries, sync lifecycle, backend connectors, Drift ORM, and Flutter Web support |
|
PowerSync Dart SDK
Load this when building a Flutter or Dart app with PowerSync.
Best practices and guidance for building Flutter apps with the PowerSync Dart SDK.
| Resource | Description |
|---|---|
| Dart API reference | Full API reference, consult only when the inline examples don't cover your case. |
| Supported Platforms | Supported platforms and features, consult for compatibility details. |
Installation
flutter pub add powersync
Setup
1. Define Schema
import 'package:powersync/powersync.dart';
const schema = Schema([
Table('todos', [
Column.text('list_id'),
Column.text('description'),
Column.integer('completed'), // 0 or 1
Column.text('created_at'),
Column.text('completed_at'),
Column.text('created_by'),
Column.text('completed_by'),
], indexes: [
Index('list', [IndexedColumn('list_id')])
]),
Table('lists', [
Column.text('created_at'),
Column.text('name'),
Column.text('owner_id'),
]),
]);
See Define the Client-Side Schema for more information.
2. Create Backend Connector
import 'package:powersync/powersync.dart';
class MyBackendConnector extends PowerSyncBackendConnector {
@override
Future<PowerSyncCredentials?> fetchCredentials() async {
final token = await myAuthService.getPowerSyncToken();
return PowerSyncCredentials(
endpoint: 'https://your-instance.powersync.journeyapps.com',
token: token,
);
}
@override
Future<void> uploadData(PowerSyncDatabase database) async {
final transaction = await database.getNextCrudTransaction();
if (transaction == null) return;
try {
for (final op in transaction.crud) {
switch (op.op) {
case UpdateType.put:
await apiClient.upsert(table: op.table, id: op.id, data: {...?op.opData, 'id': op.id});
case UpdateType.patch:
await apiClient.update(table: op.table, id: op.id, data: op.opData ?? {});
case UpdateType.delete:
await apiClient.delete(table: op.table, id: op.id);
}
}
await transaction.complete();
} catch (e) {
rethrow;
}
}
}
Use getCrudBatch instead of getNextCrudTransaction when uploading large numbers of mutations in bulk.
See Integrate with your Backend for more information.
3. Instantiate and Connect
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:powersync/powersync.dart';
late PowerSyncDatabase db;
Future<void> openDatabase() async {
final dir = await getApplicationSupportDirectory();
final path = join(dir.path, 'powersync-dart.db');
db = PowerSyncDatabase(schema: schema, path: path);
await db.initialize();
}
// Call after the user authenticates
Future<void> connect() async {
await db.connect(connector: MyBackendConnector());
}
// Call on logout
Future<void> disconnect() async {
await db.disconnectAndClear();
}
See Instantiate the PowerSync Database for more information.
Sync Streams
See sync-config.md for how to subscribe to Sync Streams when auto_subscribe is not set to true in the PowerSync Service config.
Query Patterns
See Using PowerSync: CRUD for the full API reference.
One-Time Queries
// Fetch all matching rows
final results = await db.getAll('SELECT * FROM todos WHERE list_id = ?', [listId]);
// Fetch single row — throws if not found
final todo = await db.get('SELECT * FROM todos WHERE id = ?', [id]);
// Fetch single row — returns null if not found
final todo = await db.getOptional('SELECT * FROM todos WHERE id = ?', [id]);
Reactive Queries
StreamBuilder(
stream: db.watch('SELECT * FROM todos WHERE list_id = ?', parameters: [listId]),
builder: (context, snapshot) {
if (!snapshot.hasData) return const CircularProgressIndicator();
final todos = snapshot.data!;
// build UI from todos
},
)
Writing Data
// Single mutation
await db.execute(
'INSERT INTO todos (id, list_id, description, completed) VALUES (uuid(), ?, ?, ?)',
[listId, 'Buy milk', 0],
);
// Multiple related mutations as a single unit
await db.writeTransaction((tx) async {
await tx.execute('INSERT INTO lists (id, name) VALUES (uuid(), ?)', ['Shopping']);
await tx.execute('INSERT INTO todos (id, list_id, description) VALUES (uuid(), ?, ?)', [listId, 'Milk']);
});
Row Mapping
factory Todo.fromRow(Map<String, dynamic> row) => Todo(
id: row['id'] as String,
description: row['description'] as String,
completed: row['completed'] == 1,
createdAt: DateTime.parse(row['created_at'] as String),
);
ORM — Drift
PowerSync supports Drift as an ORM via drift_sqlite_async. See the package for setup instructions and usage examples.
Flutter Web
Supported in powersync v1.9.0+. See Flutter Web Support for configuration requirements, OPFS setup for improved performance, and known limitations.