SyncClient constructor

SyncClient(
  1. Store _store,
  2. List<String> serverUrls,
  3. List<SyncCredentials> credentials, {
  4. Map<String, String>? filterVariables,
  5. List<String>? certificatePaths,
  6. int? flags,
})

Creates a Sync client associated with the given store and options. This does not initiate any connection attempts yet, call start to do so.

A minimal setup can look like this:

// Connect to a test server running on localhost using
// an unencrypted connection without authentication
SyncClient client =
    SyncClient(store, ['ws://127.0.0.1:9999'], [SyncCredentials.none()]);
client.start(); // connect and start syncing

By default, a Sync client automatically receives updates from the server once login succeeded. To configure this differently, call setRequestUpdatesMode with the wanted mode.

Server URLs

The Sync server URL is typically a WebSockets URL starting with ws:// or wss:// (for encrypted connections), for example if the server is running on localhost ws://127.0.0.1:9999.

Passing multiple URLs allows high availability and load balancing (like when using an ObjectBox Sync Server Cluster). A random URL is selected for each connection attempt.

Credentials

Use the SyncCredentials factory methods to create credentials, for example SyncCredentials.jwtIdToken(idToken). The accepted credentials types depend on your Sync server configuration.

When passing multiple credentials, can't include SyncCredentials.none.

Sync filter client variables

To configure Sync filter variables, pass variable names mapped to their value to filterVariables.

Sync client filter variables can be used in server-side Sync filters to filter out objects that do not match the filter.

Sync Flags

To adjust the behavior of the sync client, pass OBXSyncFlags to flags. These flags can be combined using bitwise OR to enable multiple options at once.

Custom Certificates

For encrypted connections, for use cases like self-signed certificates in a local development environment or custom CAs, pass certificate paths referring to the local file system to certificatePaths.

Implementation

SyncClient(
    this._store, List<String> serverUrls, List<SyncCredentials> credentials,
    {Map<String, String>? filterVariables,
    List<String>? certificatePaths,
    int? flags}) {
  if (syncClientsStorage.containsKey(_store)) {
    throw StateError('Only one sync client can be active for a store');
  }

  if (!Sync.isAvailable()) {
    throw UnsupportedError(
        'Sync is not available in the loaded ObjectBox runtime library. '
        'Please visit https://objectbox.io/sync/ for options.');
  }

  // Build options
  final options = checkObxPtr(C.sync_opt(InternalStoreAccess.ptr(_store)),
      'failed to create Sync options');
  try {
    for (final url in serverUrls) {
      withNativeString(url, (urlCStr) {
        checkObx(C.sync_opt_add_url(options, urlCStr));
      });
    }

    if (certificatePaths != null) {
      for (final certPath in certificatePaths) {
        withNativeString(certPath, (certPathCStr) {
          checkObx(C.sync_opt_add_cert_path(options, certPathCStr));
        });
      }
    }

    // Note: 0 or invalid flags are ignored by sync_opt_flags
    if (flags != null) {
      checkObx(C.sync_opt_flags(options, flags));
    }
  } catch (e) {
    // Free the options if any option method call failed (like due to invalid
    // arguments).
    C.sync_opt_free(options);
    rethrow;
  }

  // Create Sync client with options (options are freed by sync_create)
  _cSync =
      checkObxPtr(C.sync_create(options), 'failed to create Sync client');

  filterVariables?.forEach(putFilterVariable);

  if (credentials.length == 1) {
    setCredentials(credentials[0]);
  } else {
    // also covers the length == 0 case
    setMultipleCredentials(credentials);
  }

  syncClientsStorage[_store] = this;
  InternalStoreAccess.addCloseListener(_store, this, close);
}