commonMain.io.realm.kotlin.mongodb.sync.SyncConfiguration.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of library-sync-jvm Show documentation
Show all versions of library-sync-jvm Show documentation
Sync Library code for Realm Kotlin. This artifact is not supposed to be consumed directly, but through 'io.realm.kotlin:gradle-plugin:1.5.2' instead.
/*
* Copyright 2021 Realm Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.realm.kotlin.mongodb.sync
import io.realm.kotlin.Configuration
import io.realm.kotlin.LogConfiguration
import io.realm.kotlin.MutableRealm
import io.realm.kotlin.Realm
import io.realm.kotlin.TypedRealm
import io.realm.kotlin.internal.ConfigurationImpl
import io.realm.kotlin.internal.ObjectIdImpl
import io.realm.kotlin.internal.REALM_FILE_EXTENSION
import io.realm.kotlin.internal.RealmLog
import io.realm.kotlin.internal.interop.RealmInterop
import io.realm.kotlin.internal.interop.SchemaMode
import io.realm.kotlin.internal.platform.PATH_SEPARATOR
import io.realm.kotlin.internal.platform.createDefaultSystemLogger
import io.realm.kotlin.internal.platform.singleThreadDispatcher
import io.realm.kotlin.log.LogLevel
import io.realm.kotlin.log.RealmLogger
import io.realm.kotlin.mongodb.App
import io.realm.kotlin.mongodb.AppConfiguration
import io.realm.kotlin.mongodb.Credentials
import io.realm.kotlin.mongodb.User
import io.realm.kotlin.mongodb.exceptions.ClientResetRequiredException
import io.realm.kotlin.mongodb.exceptions.SyncException
import io.realm.kotlin.mongodb.internal.SyncConfigurationImpl
import io.realm.kotlin.mongodb.internal.UserImpl
import io.realm.kotlin.types.BaseRealmObject
import io.realm.kotlin.types.ObjectId
import io.realm.kotlin.types.RealmUUID
import org.mongodb.kbson.BsonBinary
import org.mongodb.kbson.BsonBinarySubType
import org.mongodb.kbson.BsonInt32
import org.mongodb.kbson.BsonInt64
import org.mongodb.kbson.BsonNull
import org.mongodb.kbson.BsonObjectId
import org.mongodb.kbson.BsonString
import org.mongodb.kbson.BsonValue
import kotlin.reflect.KClass
import kotlin.time.Duration
/**
* This enum determines how Realm sync data with the server.
*
* The server must be configured for the selected way, otherwise an error will be
* reported to [SyncConfiguration.errorHandler] when the Realm connects to the server
* for the first time.
*/
public enum class SyncMode {
/**
* Partition-based Sync. Data is selected for synchronization based on a _partition key_,
* which is a property that must be set on all objects. Server objects that
* match a given _partition value_ are then synchronized to the device.
*
* **See:** [Partitions](https://www.mongodb.com/docs/atlas/app-services/sync/data-access-patterns/partitions/)
*/
PARTITION_BASED,
/**
* Flexible Sync. Data is selected for synchronization based on one or more queries which are
* stored in a [SubscriptionSet]. All server objects that match one or more queries are then
* synchronized to the device.
*
* **See:** [Flexible Sync](https://www.mongodb.com/docs/atlas/app-services/sync/data-access-patterns/flexible-sync/)
*/
FLEXIBLE
}
/**
* Callback used to populate the initial [SubscriptionSet] when opening a Realm.
*
* This is configured through [SyncConfiguration.Builder.initialSubscriptions].
*/
public fun interface InitialSubscriptionsCallback {
/**
* Closure for adding or modifying the initial [SubscriptionSet], with the
* [MutableSubscriptionSet] as the receiver. This mirrors the API when using
* [SubscriptionSet.update] and allows for the following pattern:
*
* ```
* val user = loginUser()
* val config = SyncConfiguration.Builder(user, schema)
* .initialSubscriptions { realm: Realm -> // this: MutableSubscriptionSet
* add(realm.query())
* }
* .waitForInitialRemoteData(timeout = 30.seconds)
* .build()
* val realm = Realm.open(config)
* ```
*/
public fun MutableSubscriptionSet.write(realm: Realm)
}
/**
* Configuration options if [SyncConfiguration.Builder.waitForInitialRemoteData] is
* enabled.
*/
public data class InitialRemoteDataConfiguration(
/**
* The timeout used when downloading any initial data server the first time the
* Realm is opened.
*
* If the timeout is hit, opening a Realm will throw an
* [io.realm.mongodb.exceptions.DownloadingRealmTimeOutException].
*/
val timeout: Duration = Duration.INFINITE
)
/**
* Configuration options if [SyncConfiguration.Builder.initialSubscriptions] is
* enabled.
*/
public data class InitialSubscriptionsConfiguration(
/**
* The callback that will be called in order to populate the initial
* [SubscriptionSet] for the realm.
*/
val callback: InitialSubscriptionsCallback,
/**
* The default behavior is that [callback] is only invoked the first time
* the Realm is opened, but if [rerunOnOpen] is `true`, it will be invoked
* every time the realm is opened.
*/
val rerunOnOpen: Boolean
)
/**
* A [SyncConfiguration] is used to setup a Realm Database that can be synchronized between
* devices using Atlas Device Sync.
*
* A valid [User] is required to create a [SyncConfiguration]. See
* [Credentials] and [App.login] for more information on how to get a user object.
*
* A minimal [SyncConfiguration] can be found below.
* ```
* val app = App.create(appId)
* val user = app.login(Credentials.anonymous())
* val config = SyncConfiguration.create(user, "partition-value", setOf(YourRealmObject::class))
* val realm = Realm.open(config)
* ```
*/
public interface SyncConfiguration : Configuration {
public val user: User
// FIXME Hide this for now, as we should should not expose an internal class like this.
// Currently this is only available from `SyncConfigurationImpl`.
// See https://github.com/realm/realm-kotlin/issues/815
// public val partitionValue: PartitionValue
public val errorHandler: SyncSession.ErrorHandler
/**
* Strategy used to handle client reset scenarios.
*
* The SDK reads and writes to a local realm file. When Device Sync is enabled, the local realm
* syncs with the application backend. Some conditions can cause the realm to be unable to sync
* with Atlas. When this occurs, a client reset error is issued by the server.
*
* There is one constraint users need to be aware of when defining customized strategies when
* creating a configuration. Flexible Sync applications can **only** work in conjunction
* with [ManuallyRecoverUnsyncedChangesStrategy] whereas partition-based applications can
* **only** work in conjunction with [DiscardUnsyncedChangesStrategy].
*
* If not specified, default strategies defined in [Builder.build] will be used, depending on
* whether the application has Flexible Sync enabled. Setting this parameter manually will
* override the use of either default strategy.
*
* **See:** [Client Reset](https://www.mongodb.com/docs/realm/sdk/java/examples/reset-a-client-realm/)
*/
public val syncClientResetStrategy: SyncClientResetStrategy
/**
* The mode of synchronization for this realm.
*/
public val syncMode: SyncMode
/**
* Configuration options if initial subscriptions have been enabled for this
* realm.
*
* If this has not been enabled, `null` is returned.
*
* @see SyncConfiguration.Builder.initialSubscriptions
*/
public val initialSubscriptions: InitialSubscriptionsConfiguration?
/**
* Configuration options if downloading initial data from the server has been
* enabled for this realm.
*
* If this has not been enabled, `null` is returned.
*
* @see SyncConfiguration.Builder.waitForInitialRemoteData
*/
public val initialRemoteData: InitialRemoteDataConfiguration?
/**
* Used to create a [SyncConfiguration]. For common use cases, a [SyncConfiguration] can be
* created using the [SyncConfiguration.create] function.
*/
public class Builder private constructor(
private var user: User,
schema: Set>,
private var partitionValue: BsonValue?,
) : Configuration.SharedBuilder(schema) {
// Shouldn't default to 'default.realm' - Object Store will generate it according to which
// type of Sync is used
protected override var name: String? = null
private var errorHandler: SyncSession.ErrorHandler? = null
private var syncClientResetStrategy: SyncClientResetStrategy? = null
private var initialSubscriptions: InitialSubscriptionsConfiguration? = null
private var waitForServerChanges: InitialRemoteDataConfiguration? = null
private lateinit var appLog: RealmLog
/**
* Creates a [SyncConfiguration.Builder] for Flexible Sync. Flexible Sync must be enabled
* on the server for this to work.
*
* **See:** [Flexible Sync](https://www.mongodb.com/docs/realm/sync/data-access-patterns/flexible-sync/)
*
* @param user user used to access server side data. This will define which data is
* available from the server.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
*/
public constructor(
user: User,
schema: Set>
) : this(user, schema, null)
/**
* Creates a [SyncConfiguration.Builder] for Partition-Based Sync. Partition-Based Sync
* must be enabled on the server for this to work.
*
* **See:** [Partitions](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*
* @param user user used to access server side data. This will define which data is
* available from the server.
* @param partitionValue the partition value to use data from. The server must have been
* configured with an [ObjectId](https://www.mongodb.com/docs/v4.4/reference/method/ObjectId/) partition key for this to work.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
* **See:** [partition key](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*/
public constructor(
user: User,
partitionValue: ObjectId?,
schema: Set>
) : this(user, schema, partitionValue?.let { BsonObjectId((it as ObjectIdImpl).bytes) } ?: BsonNull)
/**
* Creates a [SyncConfiguration.Builder] for Partition-Based Sync. Partition-Based Sync
* must be enabled on the server for this to work.
*
* **See:** [Partitions](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*
* @param user user used to access server side data. This will define which data is
* available from the server.
* @param partitionValue the partition value to use data from. The server must have been
* configured with an [BsonObjectId](https://www.mongodb.com/docs/v4.4/reference/method/ObjectId/) partition key for this to work.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
* **See:** [partition key](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*/
public constructor(
user: User,
partitionValue: BsonObjectId?,
schema: Set>
) : this(user, schema, partitionValue ?: BsonNull)
/**
* Creates a [SyncConfiguration.Builder] for Partition-Based Sync. Partition-Based Sync
* must be enabled on the server for this to work.
*
* **See:** [Partitions](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*
* @param user user used to access server side data. This will define which data is
* available from the server.
* @param partitionValue the partition value to use data from. The server must have been
* configured with a [RealmUUID] partition key for this to work.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
* **See:** [partition key](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*/
public constructor(
user: User,
partitionValue: RealmUUID?,
schema: Set>
) : this(
user,
schema,
partitionValue?.let {
BsonBinary(
type = BsonBinarySubType.UUID_STANDARD,
data = it.bytes
)
} ?: BsonNull
)
/**
* Creates a [SyncConfiguration.Builder] for Partition-Based Sync. Partition-Based Sync
* must be enabled on the server for this to work.
*
* @param user user used to access server side data. This will define which data is
* available from the server.
* @param partitionValue the partition value to use data from. The server must have been
* configured with a Int partition key for this to work.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
*/
public constructor(
user: User,
partitionValue: Int?,
schema: Set>
) : this(user, schema, partitionValue?.let { BsonInt32(it) } ?: BsonNull)
/**
* Creates a [SyncConfiguration.Builder] for Partition-Based Sync. Partition-Based Sync
* must be enabled on the server for this to work.
*
* **See:** [Partitions](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*
* @param user user used to access server side data. This will define which data is
* available from the server.
* @param partitionValue the partition value to use data from. The server must have been
* configured with a Long partition key for this to work.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
*/
public constructor(
user: User,
partitionValue: Long?,
schema: Set>
) : this(user, schema, partitionValue?.let { BsonInt64(it) } ?: BsonNull)
/**
* Creates a [SyncConfiguration.Builder] for Partition-Based Sync. Partition-Based Sync
* must be enabled on the server for this to work.
*
* **See:** [Partitions](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*
* @param user user used to access server side data. This will define which data is
* available from the server.
* @param partitionValue the partition value to use data from. The server must have been
* configured with a String partition key for this to work.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
*/
public constructor(
user: User,
partitionValue: String?,
schema: Set>
) : this(user, schema, partitionValue?.let { BsonString(it) } ?: BsonNull)
init {
if (!user.loggedIn) {
throw IllegalArgumentException("A valid, logged in user is required.")
}
// Prime builder with log configuration from AppConfiguration
appLog = (user as UserImpl).app.configuration.log
this.logLevel = appLog.configuration.level
this.userLoggers = appLog.configuration.loggers
this.removeSystemLogger = true
}
/**
* Sets the error handler used by Synced Realms when reporting errors with their session.
*
* @param errorHandler lambda to handle the error.
*/
public fun errorHandler(errorHandler: SyncSession.ErrorHandler): Builder =
apply { this.errorHandler = errorHandler }
/**
* Sets the strategy that would handle the client reset by this synced Realm.
*
* Flexible Sync applications only accept [ManuallyRecoverUnsyncedChangesStrategy] whereas
* partition-based applications only accept [DiscardUnsyncedChangesStrategy].
*
* In case no strategy is defined a default one (which does not do any data migration and
* its only job is logging information on the client reset process itself) will be used.
*
* @param resetStrategy custom strategy to handle client reset.
*/
public fun syncClientResetStrategy(resetStrategy: SyncClientResetStrategy): Builder =
apply {
if (partitionValue == null && resetStrategy is DiscardUnsyncedChangesStrategy) {
throw IllegalArgumentException("DiscardUnsyncedChangesStrategy is not supported on Flexible Sync")
}
if (partitionValue != null && resetStrategy is ManuallyRecoverUnsyncedChangesStrategy) {
throw IllegalArgumentException("ManuallyRecoverUnsyncedChangesStrategy is not supported on Partition-based Sync")
}
this.syncClientResetStrategy = resetStrategy
}
override fun log(level: LogLevel, customLoggers: List): Builder =
apply {
// Will clear any primed configuration
this.logLevel = level
this.userLoggers = customLoggers
this.removeSystemLogger = false
}
/**
* Sets the filename of the realm file.
*
* If a [SyncConfiguration] is built without having provided a [name], Realm will
* generate a file name based on the provided [partitionValue] and [AppConfiguration.appId]
* which will have a `.realm` extension.
*
* @throws IllegalArgumentException if the name includes a path separator or if the name is
* `.realm`.
*/
override fun name(name: String): Builder = apply {
checkName(name)
this.name = name
}
/**
* Setting this will cause the Realm to download all known changes from the server the
* first time a Realm is opened. The Realm will not open until all the data has been
* downloaded. This means that if a device is offline the Realm will not open.
*
* Since downloading all changes can be a lengthy operation that might block the UI
* thread, Realms with this setting enabled should only be opened on background threads.
*
* This check is only enforced the first time a Realm is created, except if
* [initialSubscriptions] has been configured with `rerunOnOpen = true`. In that case,
* server data is downloaded every time the Realm is opened.
*
* If it is conditional when server data should be downloaded, this can be controlled
* through [SyncSession.downloadAllServerChanges], e.g like this:
*
* ```
* val user = loginUser()
* val config = SyncConfiguration.Builder(user, schema)
* .initialSubscriptions { realm ->
* add(realm.query())
* }
* .build()
* val realm = Realm.open(config)
* if (downloadData) {
* realm.syncSession.downloadAllServerChanges(timeout = 30.seconds)
* }
* ```
*
* @param timeout how long to wait for the download to complete before an
* [io.realm.kotlin.mongodb.exceptions.DownloadingRealmTimeOutException] is thrown when opening
* the Realm.
*/
public fun waitForInitialRemoteData(timeout: Duration = Duration.INFINITE): Builder =
apply {
this.waitForServerChanges = InitialRemoteDataConfiguration(timeout)
}
/**
* Define the initial [io.realm.mongodb.sync.SubscriptionSet] for the Realm. This will only
* be executed the first time the Realm file is opened (and the file created).
*
* If [waitForInitialRemoteData] is configured as well, the realm file isn't fully
* opened until all subscription data also has been downloaded.
*
* @param rerunOnOpen If `true` this closure will rerun every time the Realm is opened,
* this makes it possible to update subscription queries with e.g. new timestamp information
* or other query data that might change over time. If [waitForInitialRemoteData] is also
* set, the Realm will download the new subscription data every time the Realm is opened,
* rather than just the first time.
* @param initialSubscriptionBlock closure making it possible to modify the set of
* subscriptions.
*/
public fun initialSubscriptions(
rerunOnOpen: Boolean = false,
initialSubscriptionBlock: InitialSubscriptionsCallback
): Builder = apply {
if (partitionValue != null) {
throw IllegalStateException(
"Defining initial subscriptions is only available if " +
"the configuration is for Flexible Sync."
)
}
this.initialSubscriptions = InitialSubscriptionsConfiguration(
initialSubscriptionBlock,
rerunOnOpen
)
}
override fun build(): SyncConfiguration {
val allLoggers = userLoggers.toMutableList()
// TODO This will not remove the system logger if it was added in AppConfiguration and
// no overrides are done for this builder. But as removeSystemLogger() is not public
// and most people will only specify loggers on the AppConfiguration this is OK for
// now.
if (!removeSystemLogger) {
allLoggers.add(0, createDefaultSystemLogger(Realm.DEFAULT_LOG_TAG))
}
// Set default error handler after setting config logging logic
if (this.errorHandler == null) {
this.errorHandler = object : SyncSession.ErrorHandler {
private val fallbackErrorLogger: RealmLogger by lazy {
createDefaultSystemLogger("SYNC_ERROR")
}
override fun onError(session: SyncSession, error: SyncException) {
error.message?.let {
// Grab user logger if present or use fallback to at least show something
// in case no loggers are to be found
if (userLoggers.isNotEmpty()) {
userLoggers[0].log(LogLevel.WARN, it)
} else {
fallbackErrorLogger.log(LogLevel.WARN, it)
}
}
}
}
}
// Don't forget: Flexible Sync only supports Manual Client Reset
if (syncClientResetStrategy == null) {
syncClientResetStrategy = when (partitionValue) {
null -> object : ManuallyRecoverUnsyncedChangesStrategy {
override fun onClientReset(
session: SyncSession,
exception: ClientResetRequiredException
) {
appLog.error("Client Reset required on Realm: ${exception.originalFilePath}")
}
}
else -> object : DiscardUnsyncedChangesStrategy {
override fun onBeforeReset(realm: TypedRealm) {
appLog.info("Client Reset is about to happen on Realm: ${realm.configuration.path}")
}
override fun onAfterReset(before: TypedRealm, after: MutableRealm) {
appLog.info("Client Reset complete on Realm: ${after.configuration.path}")
}
override fun onError(
session: SyncSession,
exception: ClientResetRequiredException
) {
appLog.error("Discard unsynced changes client reset failed on Realm: ${exception.originalFilePath}")
}
}
}
}
// ObjectStore uses a different default value for Flexible Sync than we want,
// so inject our default name if no user provided name was found
if (partitionValue == null && name == null) {
name = Realm.DEFAULT_FILE_NAME
}
val fullPathToFile = getAbsolutePath(name)
val fileName = fullPathToFile.substringAfterLast(PATH_SEPARATOR)
val directory = fullPathToFile.removeSuffix("$PATH_SEPARATOR$fileName")
val baseConfiguration = ConfigurationImpl(
directory,
fileName,
schema,
LogConfiguration(logLevel, allLoggers),
maxNumberOfActiveVersions,
notificationDispatcher ?: singleThreadDispatcher(fileName),
writeDispatcher ?: singleThreadDispatcher(fileName),
schemaVersion,
SchemaMode.RLM_SCHEMA_MODE_ADDITIVE_DISCOVERED,
encryptionKey,
compactOnLaunchCallback,
null, // migration is not relevant for sync,
initialDataCallback,
partitionValue == null,
inMemory
)
return SyncConfigurationImpl(
baseConfiguration,
partitionValue,
user as UserImpl,
errorHandler!!, // It will never be null: either default or user-provided
syncClientResetStrategy!!, // It will never be null: either default or user-provided
initialSubscriptions,
waitForServerChanges
)
}
private fun getAbsolutePath(name: String?): String {
// In order for us to generate the path we need to provide a full-fledged sync
// configuration which at this point we don't yet have, so we have to create a
// temporary one so that we can return the actual path to a sync Realm using the
// realm_app_sync_client_get_default_file_path_for_realm function below
val absolutePath: String = when (partitionValue == null) {
true -> RealmInterop.realm_flx_sync_config_new((user as UserImpl).nativePointer)
false -> RealmInterop.realm_sync_config_new(
(user as UserImpl).nativePointer,
partitionValue!!.toJson()
)
}.let { auxSyncConfig ->
RealmInterop.realm_app_sync_client_get_default_file_path_for_realm(
(user as UserImpl).app.nativePointer,
auxSyncConfig,
name
)
}
// Remove .realm extension if user has overridden filename manually
return if (name != null) {
absolutePath.removeSuffix(REALM_FILE_EXTENSION)
} else {
absolutePath
}
}
}
public companion object {
/**
* Creates a sync configuration for Flexible Sync with default values for all
* optional configuration parameters.
*
* Flexible Sync uses a concept called subscription sets to define which data gets
* uploaded and downloaded to the device. See [SubscriptionSet] for more information.
*
* **See:** [Flexible Sync](https://www.mongodb.com/docs/atlas/app-services/sync/data-access-patterns/flexible-sync/)
*
* @param user the [User] who controls the realm.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
* @throws IllegalArgumentException if the user is not valid and logged in.
*/
public fun create(user: User, schema: Set>): SyncConfiguration =
Builder(user, schema).build()
/**
* Creates a sync configuration for Partition-based Sync with default values for all
* optional configuration parameters.
*
* **See:** [Partitions](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*
* @param user the [User] who controls the realm.
* @param partitionValue the partition value that defines which data to sync to the realm.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
* @throws IllegalArgumentException if the user is not valid and logged in.
*/
public fun create(
user: User,
partitionValue: String?,
schema: Set>
): SyncConfiguration =
Builder(user, partitionValue, schema).build()
/**
* Creates a sync configuration for Partition-based Sync with default values for all
* optional configuration parameters.
*
* **See:** [Partitions](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*
* @param user the [User] who controls the realm.
* @param partitionValue the partition value that defines which data to sync to the realm.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
* @throws IllegalArgumentException if the user is not valid and logged in.
*/
public fun create(
user: User,
partitionValue: Int?,
schema: Set>
): SyncConfiguration =
Builder(user, partitionValue, schema).build()
/**
* Creates a sync configuration for Partition-based Sync with default values for all
* optional configuration parameters.
*
* * **See:** [Partitions](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*
* @param user the [User] who controls the realm.
* @param partitionValue the partition value that defines which data to sync to the realm.
* @param schema the classes of the schema. The elements of the set must be direct class
* literals.
* @throws IllegalArgumentException if the user is not valid and logged in.
*/
public fun create(
user: User,
partitionValue: Long?,
schema: Set>
): SyncConfiguration =
Builder(user, partitionValue, schema).build()
/**
* Creates a sync configuration for Partition-based Sync with default values for all
* optional configuration parameters.
*
* @param user the [User] who controls the realm.
* @param partitionValue the partition value that defines which data to sync to the realm.
* @param schema the classes of the schema. The elements of the set must be direct class literals.
* @throws IllegalArgumentException if the user is not valid and logged in.
* * **See:** [partition key](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*/
public fun create(user: User, partitionValue: ObjectId?, schema: Set>): SyncConfiguration =
Builder(user, partitionValue, schema).build()
/**
* Creates a sync configuration for Partition-based Sync with default values for all
* optional configuration parameters.
*
* @param user the [User] who controls the realm.
* @param partitionValue the partition value that defines which data to sync to the realm.
* @param schema the classes of the schema. The elements of the set must be direct class literals.
* @throws IllegalArgumentException if the user is not valid and logged in.
* * **See:** [partition key](https://www.mongodb.com/docs/realm/sync/data-access-patterns/partitions/)
*/
public fun create(user: User, partitionValue: RealmUUID?, schema: Set>): SyncConfiguration =
Builder(user, partitionValue, schema).build()
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy