Skip to main content

Data Sync using Sync Gateway

Description — Synchronize local Couchbase Lite data with Sync Gateway using the replicator API.

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://.

note

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.

Example 1. Replication Configuration and Initialization
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:

Example 2. Configure the Sync Gateway Target
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.

Example 3. Configure Direction and Continuous Mode
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:

Example 4. Tune Retry Behavior
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:

Example 5. Use Basic Authentication
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:

Example 6. Use Session Authentication
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:

In Community Edition, use certificate pinning or a trusted custom root chain instead of self-signed-only mode.

Example 7. Trust a Custom Root Certificate Chain
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.

Example 8. Add Custom 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.

Example 9. Filter Replication Per Collection
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.

Example 10. Disable Auto-purge
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.

Example 11. Create and Start the Replicator
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.

Example 12. Reset the Local Checkpoint
await replicator.start(reset: true);

Monitor​

Change Listeners and Status​

Observe the replicator with Replicator.changes or Replicator.addChangeListener.

Example 13. Monitor Replication Status
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:

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.

Example 14. Monitor Replicated Documents
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.

Example 15. Inspect Pending Documents
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.

Example 16. Stop the Replicator
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:// or wss://.
  • 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.