Data Sync using Sync Gateway
Introduction​
Couchbase Lite for Dart synchronizes local data with Sync Gateway through
Replicator. A replicator connects a local database or collection set to a
remote Sync Gateway database and transfers document changes in one or both
directions.
This page covers the main Sync Gateway replication concepts and the Dart API used to configure, start, monitor, and stop replication.
Replication Concepts​
Replication can be configured at the collection level. Each configured
collection can also have its own CollectionConfiguration, which is where
you attach filters, channels, document IDs, and conflict resolution rules.
Use Sync Gateway replication when your application needs to sync local data with a central server deployment instead of directly with another edge device.
Replication Protocol​
Couchbase Lite uses a WebSocket-based replication protocol. The remote URL must
therefore use ws:// or wss://.
The replication protocol is not compatible with CouchDB-style endpoints.
The protocol is optimized for throughput, so document delivery order is not guaranteed. Avoid application logic that depends on a particular arrival order in replication callbacks.
Scopes and Collections​
The local collections configured in the replicator must also exist in Sync Gateway with the same scope and collection names. If the server-side configuration changes and removes a collection that is currently being synced, the replicator eventually stops with an error.
If you only add the default collection to the replicator, Couchbase Lite syncs the default collection on both sides.
Configuration Summary​
Create a ReplicatorConfiguration, add the collections to replicate,
configure authentication and transport settings, then create and start the
replicator.
final config = ReplicatorConfiguration(
target: UrlEndpoint(
Uri.parse('wss://example.com:4984/travel-sample'),
),
authenticator: BasicAuthenticator(
username: 'cbl-user-01',
password: 'secret',
),
)
..replicatorType = ReplicatorType.pushAndPull
..continuous = true
..addCollection(collection);
final replicator = await Replicator.create(config);
await replicator.start();
Configure​
Configure Target​
Use UrlEndpoint to specify the remote Sync Gateway database:
final target = UrlEndpoint(
Uri.parse('wss://example.com:4984/travel-sample'),
);
final config = ReplicatorConfiguration(target: target)..addCollection(
collection,
);
Sync Mode​
Use ReplicatorConfiguration.replicatorType to choose push, pull, or
bidirectional replication. Use ReplicatorConfiguration.continuous to keep
the replicator running and reconnecting as needed.
final config = ReplicatorConfiguration(target: target)
..replicatorType = ReplicatorType.pushAndPull
..continuous = true
..addCollection(collection);
Retry Configuration​
The replicator automatically retries transient connectivity issues. You can adjust the retry behavior with:
ReplicatorConfiguration.heartbeatReplicatorConfiguration.maxAttemptsReplicatorConfiguration.maxAttemptWaitTime
final config = ReplicatorConfiguration(target: target)
..heartbeat = const Duration(seconds: 120)
..maxAttempts = 6
..maxAttemptWaitTime = const Duration(minutes: 2)
..addCollection(collection);
User Authorization​
Use ReplicatorConfiguration.authenticator to configure the credentials the
client presents to Sync Gateway.
Basic Authentication​
Use BasicAuthenticator when Sync Gateway expects username/password
credentials:
final config = ReplicatorConfiguration(
target: target,
authenticator: BasicAuthenticator(
username: 'cbl-user-01',
password: 'secret',
),
)..addCollection(collection);
Session Authentication​
Use SessionAuthenticator if your application already has a Sync Gateway
session token:
final config = ReplicatorConfiguration(
target: target,
authenticator: SessionAuthenticator(
sessionId: sessionId,
),
)..addCollection(collection);
Server Authentication​
By default, the client validates the Sync Gateway certificate against the platform trust store. For custom deployments you can also:
- accept only self-signed certificates with
ReplicatorConfiguration.acceptOnlySelfSignedServerCertificate(Enterprise Edition only) - pin a specific server certificate with
ReplicatorConfiguration.pinnedServerCertificate - trust a custom root chain with
ReplicatorConfiguration.trustedRootCertificates
In Community Edition, use certificate pinning or a trusted custom root chain instead of self-signed-only mode.
final config = ReplicatorConfiguration(
target: target,
trustedRootCertificates: PemData(rootCertificatePem),
)..addCollection(collection);
Custom Headers​
Use ReplicatorConfiguration.headers when Sync Gateway or an intermediate
proxy requires extra HTTP headers.
final config = ReplicatorConfiguration(
target: target,
headers: {'X-Correlation-ID': 'sync-42'},
)..addCollection(collection);
Replication Filters​
Attach a CollectionConfiguration when adding a collection if you need
document ID filters, channel filters, or push/pull filters.
final collectionConfig = CollectionConfiguration(
channels: ['customer-a'],
documentIds: ['hotel-123', 'hotel-456'],
pushFilter: (document, flags) {
return document.string('type') == 'hotel';
},
pullFilter: (document, flags) {
return !flags.contains(DocumentFlag.deleted);
},
);
final config = ReplicatorConfiguration(target: target)
..addCollection(collection, collectionConfig);
Auto-purge on Channel Access Revocation​
ReplicatorConfiguration.enableAutoPurge defaults to true. When enabled,
documents are automatically removed from the local database if the user loses
access to them on the server.
Set it to false if your application needs to keep those documents locally and
handle revocation explicitly.
final config = ReplicatorConfiguration(
target: target,
enableAutoPurge: false,
)..addCollection(collection);
Delta Sync​
Delta sync is negotiated with Sync Gateway when the server side allows it. No extra client-side switch is needed beyond using a normal replicator against a compatible Sync Gateway deployment.
Initialize​
Start Replicator​
Use Replicator.create followed by Replicator.start.
final replicator = await Replicator.create(config);
await replicator.start();
Checkpoint Starts​
If you need to ignore the existing local checkpoint and rescan from the
beginning, start the replicator with reset: true.
await replicator.start(reset: true);
Monitor​
Change Listeners and Status​
Observe the replicator with Replicator.changes or
Replicator.addChangeListener.
await for (final change in replicator.changes()) {
final status = change.status;
print(status.activity);
print(status.progress);
print(status.error);
}
The activity state is one of:
ReplicatorActivityLevel.stoppedReplicatorActivityLevel.offlineReplicatorActivityLevel.connectingReplicatorActivityLevel.idleReplicatorActivityLevel.busy
Monitor Document Changes​
Use Replicator.documentReplications or
Replicator.addDocumentReplicationListener if you need per-document
replication events. Attach the listener before calling Replicator.start.
If you add it after the replicator has started, stop and start the replicator
again before expecting document-level events.
await for (final replication in replicator.documentReplications()) {
for (final document in replication.documents) {
print('${document.scope}.${document.collection}/${document.id}');
print(document.error);
}
}
Documents Pending Push​
Use Replicator.pendingDocumentIdsInCollection and
Replicator.isDocumentPendingInCollection to inspect local changes that
have not yet been pushed.
final pendingIds = await replicator.pendingDocumentIdsInCollection(collection);
final isPending = await replicator.isDocumentPendingInCollection(
'hotel-123',
collection,
);
Stop​
Call Replicator.stop to stop the replication. The stop is asynchronous;
watch the status until it reaches
ReplicatorActivityLevel.stopped.
await replicator.stop();
Error Handling​
Transient connectivity issues typically surface as offline or connecting
states before the replicator reconnects. Fatal errors are exposed through
ReplicatorStatus.error.
Authentication failures and TLS failures usually appear as network or HTTP errors in the replicator status. Handle them explicitly in your replication observer so your application can distinguish misconfiguration from temporary network loss.
Certificate Pinning​
Certificate pinning is available through
ReplicatorConfiguration.pinnedServerCertificate. Use it when the server
certificate is known ahead of time and you want to reject any other certificate
chain, even if the platform would otherwise trust it.
Troubleshooting​
When replication does not behave as expected:
- Inspect
ReplicatorStatus.error. - Verify that the Sync Gateway URL uses
ws://orwss://. - Confirm that every replicated local collection exists remotely with the same scope and collection name.
- Check your TLS settings, server certificate trust, and user credentials.
- Enable Couchbase Lite logging if you need lower-level diagnostics.