From 347207485dc47d1ae49c855368bf70f3e8c9f432 Mon Sep 17 00:00:00 2001 From: cbullinger Date: Fri, 29 Sep 2023 11:36:01 -0400 Subject: [PATCH] alternate formatting --- .../com/mongodb/realm/realmkmmapp/SyncTest.kt | 11 +- .../SyncTest.snippet.define-synced-realm.kt | 10 +- .../SyncTest.snippet.write-to-synced-realm.kt | 1 + source/sdk/kotlin/sync/add-sync-to-app.txt | 241 +++++++++--------- source/sdk/kotlin/sync/subscribe.txt | 2 +- 5 files changed, 129 insertions(+), 136 deletions(-) diff --git a/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/SyncTest.kt b/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/SyncTest.kt index 95500afcecc..a8f5246ed68 100644 --- a/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/SyncTest.kt +++ b/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/SyncTest.kt @@ -59,16 +59,12 @@ class SyncTest: RealmTest() { schema = setOf(ExampleSyncObject_List::class, ExampleSyncObject_Item::class) ) // Define an initial subscription with queries that include - // the user's lists and incomplete items + // the user's lists with incomplete items .initialSubscriptions{ realm -> - add(realm.query( - "ownerId == $0", myAuthenticatedUser.id - ), + add(realm.query("ownerId == $0", myAuthenticatedUser.id), name = "user-lists" ) - add(realm.query( - "complete = false" - ), + add(realm.query("complete = false"), name = "incomplete-items" ) } @@ -93,6 +89,7 @@ class SyncTest: RealmTest() { ownerId = myAuthenticatedUser.id items.add(ExampleSyncObject_Item().apply { name = "Check email" + complete = false }) } copyToRealm(list) diff --git a/source/examples/generated/kotlin/SyncTest.snippet.define-synced-realm.kt b/source/examples/generated/kotlin/SyncTest.snippet.define-synced-realm.kt index 54eb56ba6b4..f1253cbc735 100644 --- a/source/examples/generated/kotlin/SyncTest.snippet.define-synced-realm.kt +++ b/source/examples/generated/kotlin/SyncTest.snippet.define-synced-realm.kt @@ -7,16 +7,12 @@ val config = schema = setOf(List::class, Item::class) ) // Define an initial subscription with queries that include - // the user's lists and incomplete items + // the user's lists with incomplete items .initialSubscriptions{ realm -> - add(realm.query( - "ownerId == $0", myAuthenticatedUser.id - ), + add(realm.query("ownerId == $0", myAuthenticatedUser.id), name = "user-lists" ) - add(realm.query( - "complete = false" - ), + add(realm.query("complete = false"), name = "incomplete-items" ) } diff --git a/source/examples/generated/kotlin/SyncTest.snippet.write-to-synced-realm.kt b/source/examples/generated/kotlin/SyncTest.snippet.write-to-synced-realm.kt index ce3aed8e0f9..5f12abca32d 100644 --- a/source/examples/generated/kotlin/SyncTest.snippet.write-to-synced-realm.kt +++ b/source/examples/generated/kotlin/SyncTest.snippet.write-to-synced-realm.kt @@ -6,6 +6,7 @@ realm.write { ownerId = myAuthenticatedUser.id items.add(Item().apply { name = "Check email" + complete = false }) } copyToRealm(list) diff --git a/source/sdk/kotlin/sync/add-sync-to-app.txt b/source/sdk/kotlin/sync/add-sync-to-app.txt index 170806e5545..de49ea35dc0 100644 --- a/source/sdk/kotlin/sync/add-sync-to-app.txt +++ b/source/sdk/kotlin/sync/add-sync-to-app.txt @@ -2,9 +2,9 @@ .. _kotlin-sync: .. _kotlin-sync-overview: -====================================== -Add Device Sync to an App - Kotlin SDK -====================================== +============================================= +Add Device Sync to an App (Copy) - Kotlin SDK +============================================= .. contents:: On this page :local: @@ -13,35 +13,55 @@ Add Device Sync to an App - Kotlin SDK :class: singlecol This page contains information about Device Sync, its basic concepts, -and how to add Sync to a client App with the Realm Kotlin SDK. +and how to add Sync to a client app with the Realm Kotlin SDK. +Once you have added Sync to your app, you can access a synced realm +from the client. Refer to :ref:`` for +more information. For a detailed explanation of Device Sync, refer to :ref:`realm-sync-get-started` in the Atlas App Services documentation. Already familiar with Device Sync? Skip ahead to the -:ref:`` section +:ref:`` section to get started. .. note:: Flexible Sync Mode - This page describes how to use Device Sync with Flexible Sync Mode. + This page describes how to add Device Sync with Flexible Sync Mode. If your App Services backend uses the older Partition-Based Sync, refer to :ref:`kotlin-partition-based-sync`. - We recommend that new apps use Flexible Sync. + We recommend that you use Flexible Sync. + +.. _kotlin-add-sync-to-app-prereqs: + +Prerequisites +------------- + +You can add Device Sync to an app in several ways, depending on the state +of your app and your data. This guide describes how to add Sync to an +existing client app using Development Mode. This guide assumes that your +app uses the Realm Kotlin SDK and that you have already defined a data model. + +Because Device Sync connects your client app to the App Services backend +through an Atlas App Services App, you need to following before you +can get started: + +#. An Atlas App Services App with authentication enabled. To learn how, refer to :ref:`` in the App Services documentation. +#. Confirm that your app can connect to the App Services backend. To learn how, refer to :ref:``. .. _kotlin-example-sync-data-model: About the Examples on this Page ------------------------------- -The examples on this page use an example Todo App with a defined -data model that includes a ``List`` object, which contains a list -of ``Item`` objects: +The examples on this page refer to an example Kotlin Todo app with an +already defined data model that includes a ``List`` object containing +a list of ``Item`` objects: .. literalinclude:: /examples/generated/kotlin/SchemaSync.snippet.sync-to-do-model.kt :language: kotlin - :caption: Example ToDo App data model + :caption: Example ToDo app data model .. _kotlin-realm-sync: .. _kotlin-flexible-sync-fundamentals: @@ -52,124 +72,98 @@ Device Sync **Device Sync** is an Atlas App Services feature that automatically synchronizes data between client applications using a Realm SDK and an Atlas App Services backend linked to a MongoDB Atlas cluster. -When a client device is online, Sync synchronizes data asynchronously in a -background thread between the device and your backend Atlas App. +When a client device is online, Sync uploads and downloads changesets +asynchronously in a background thread between the device and your +backend Atlas App. -You determine what data syncs between your client App and an Atlas App -Services backend by defining eligible data and user permissions to that data: +The data that syncs between your client app and the App +Services backend is determined by a user's permissions to eligible data. -- Eligible data is determined by the following: - - - Your Device Sync data model: The objects eligible to sync. - - Your subscription queries: The one or more client-side queries to eligible objects that define what can sync. +Eligible data is determined by the following: -- Role-based user permissions: The read and write permissions that control whether eligible - data syncs *to* or *from* the backend for a specific user. +- Your Device Sync data model: The objects you want to sync. +- Your subscription queries: The one or more client-side queries to those objects that specify the eligible data. + +The role-based permissions that you define in App Services control whether +that eligible data successfully syncs *to* or *from* the backend for an +authorized user. Data Model ~~~~~~~~~~ +You can define your Device Sync data model in your client app first or +in Atlas first. The following describes the client-first approach using +Development Mode. If you already have data in Atlas and would +prefer to define your data model through Atlas first, refer to +:ref:`` in the App Services documentation. + The Device Sync data model defines the object types that you can sync. It contains a client-side and server-side schema: -- **Realm schema**: the object model in your client App that defines your +- **Realm schema**: the object model in your client app that defines your data in Kotlin. - **App Services schema**: the schema in Atlas App Services that defines your data in BSON. Both schemas must be consistent with each other to sync data. -You can define your data model in your client App first or in Atlas -first: +After you :ref:`define an object model ` +directly in your client app code, you can use **Development Mode** to +generate a matching App Services schema automatically. Development Mode +is a configuration setting that allows Device Sync +to infer and update schemas based on client-side data models when you +sync data from the client. To learn more, refer to :ref:`` +in the App Services documentation. -- Client First: You can define an object model model directly in your client App code, and then use Device Sync Development Mode to generate a matching App Services schema automatically. **Development Mode** is a configuration setting that allows Device Sync to infer and update schemas based on client-side data models when you sync data from the client. To learn more, refer to :ref:`` in the App Services documentation. - For more information on defining your data model in a client App first, refer to :ref:`` in the App Services documentation. -- Atlas First: If you already have data in Atlas, you can generate an App Services Schema by sampling that data. Then, you can generate a matching Realm schema in Kotlin that you can copy and use in your client App. - For more information on defining your data model through Atlas first, refer to :ref:`` in the App Services documentation. - -.. tabs:: - - .. tab:: Client-First - :tabid: client-first - - You can define an object model model directly in your client App code, and then Device Sync can generate a matching App Services schema automatically using **Development Mode**. - Development Mode is a configuration setting that allows Device Sync to infer and update schemas based on client-side data models when you sync data from the client. To learn more, - refer to :ref:`` in the App Services documentation. - - For more information on defining your data model in a client - app first, refer to :ref:`` - in the App Services documentation. - - .. tab:: Atlas-First - :tabid: atlas-first - - If you already have data in Atlas, you can generate an App Services Schema by sampling that data. Then, you can generate a matching - Realm schema in Kotlin that you can copy and use in your client App. +Subscriptions +~~~~~~~~~~~~~ - For more information on defining your data model through Atlas first, refer to :ref:`` - in the App Services documentation. +A **subscription** is a client-side query to objects in your data model. +App Services only syncs objects that match the query. You can define multiple +queries in your client app, but you can only query objects in your +data model. -For our example App, we have already defined our data model -in our client App, so we will be using Development Mode to -automatically generate our App Services schema. Refer to the :ref:`` section for the data model -example. +App Services ensures that your client-side queries are consistent with +your App Services schema through **queryable fields**. These are the +fields from your data model that can be used in a subscription query. You +cannot subscribe to a query that contains a non-queryable field. -Subscriptions -~~~~~~~~~~~~~ +When Development Mode is enabled, App Services automatically +adds the fields that appear in your client queries as queryable fields. +You can also manually add and remove queryable fields through the +App Services UI. For more information, refer to :ref:`` +in the App Services documentation. -You use your data model to define client-side subscriptions to -the data that you want to sync. **Subscriptions** are definable -queries to objects in your data model, and App Services only syncs objects -that match the query. - -Query objects must be in your data model, and queries can only contain -specific fields. The specific fields that can be used in a subscription -query are called **queryable fields**. When Development -Mode is enabled, App Services automatically adds the fields that appear -your client queries as queryable fields. You can manage your queryable fields in the App Services UI. -For more information, refer to :ref:`` in the App -Services documentation. - -For our example App, our data model contains an ``Item`` object -with a ``complete`` field. Because we have Development Mode enabled, -if we were to define a subscription to query -only incomplete items, then App Services would automatically add ``complete`` -as a queryable field when we sync the data. +For our example app, our data model contains an ``Item`` object +with a ``complete`` field. When Development Mode is enabled and we define a +subscription to query only incomplete items, then App Services would +automatically add ``complete`` as a queryable field when we sync the data. User Permissions ~~~~~~~~~~~~~~~~ App Services uses **role-based permissions** to control what individual -users can and cannot do with your app's data: +users can and cannot do with your app's data when they have a network +connection: -- When a user has permission to read or write an eligible object, Atlas syncs - that object to the client. -- When a user has permission to write an eligible object, Atlas syncs that - object to the backend. +- When a user has read permissions, Atlas automatically syncs eligible + data to the client. +- When a user write permissions, Atlas automatically syncs any local changes + to eligible data to the backend. You can define and manage roles in the App Services UI. When you enable Sync, you select a default role, which you can modify later. For more information, refer to :ref:`` in the App Services documentation. -.. _kotlin-add-sync-to-app-prereqs: - -Prerequisites -------------- - -Before you can add Sync to an App, you need the following: - -- An Atlas App Services App with authentication enabled. - For more information, refer to :ref:`` - in the App Services documentation. -- A client App that can connect to your App Services backend. - For more information, refer to :ref:``. - .. _kotlin-enable-sync-in-app-services: Enable Device Sync in App Services ---------------------------------- +You must first enable Device Sync in your Atlas App Services App before +you can add Sync to your client app. + To enable Device Sync in your App, complete the steps outlined in :ref:`Configure and Enable Atlas Device Sync ` procedure in the App Services documentation. @@ -187,17 +181,17 @@ documentation. For more information, refer to :ref:`` in the App Services documentation. -For our example App, we enable Device Sync with Development Mode -enabled and add the default "User can read and write all data -default" role. This means that, for an authorized user, Atlas will -sync eligible data from Atlas to read from the client *and* -sync eligible data from the client to write to the backend. +For our example app, we enable Device Sync with Development Mode, and +then add the default "User can read and write all data +default" role. This means that, for an authorized user with a network +connection, Atlas will sync eligible data from Atlas to the client +*and* from the client to write to the backend. Add Sync to Your Client App --------------------------- After you've configured and enabled Sync in Atlas App Services, -you can add Sync to your client App. +you can add Sync to your client app. .. procedure:: @@ -208,11 +202,12 @@ you can add Sync to your client App. .. step:: Connect to the App Services backend - Pass your App ID to an ``App`` client to initialize the App. To get your App ID from the App - Services UI, refer to :ref:`Find Your App ID ` in the + Pass your App ID to an ``App`` client to initialize the App. To get + your App ID from the App Services UI, refer to + :ref:`Find Your App ID ` in the App Services documentation. - For our example App, we pass our App ID to initialize an ``App`` with + For our example app, we pass our App ID to initialize an ``App`` with default configuration values: .. literalinclude:: /examples/generated/kotlin/SyncTest.snippet.connect-to-backend.kt @@ -223,15 +218,15 @@ you can add Sync to your client App. .. step:: Authenticate a User - Authenticate a user in your client project with a supported + Authenticate a user in your client app with a supported authentication provider that you have enabled. - For our example App, we log in a user using anonymous authentication: + For our example app, we log in a user using anonymous authentication: .. literalinclude:: /examples/generated/kotlin/SyncTest.snippet.authenticate-user.kt :language: kotlin - For more information on authenticating users in your App, refer to + For more information on authenticating users in your app, refer to :ref:``. .. step:: Define the Sync Configuration @@ -244,7 +239,7 @@ you can add Sync to your client App. The ``SyncConfiguration`` object requires the following: - - **User**: the authenticated user object + - **User**: the authenticated user object. - **Schema**: all object types that you want to include in this realm. - **Initial Subscription**: the subscription query that specifies the data to sync when the synced realm is @@ -255,10 +250,11 @@ you can add Sync to your client App. For additional configuration parameters, refer to :ref:``. - For our example App, we define a configuration with a schema that includes - our ``List`` and ``Item`` objects, and an initial subscription - that queries all ``List`` objects that the user owns - and all incomplete ``Item`` objects: + For our example app, we define a configuration with: + + - a schema that includes our ``List`` and ``Item`` objects + - an initial subscription that queries all ``List`` objects + that the user owns and all incomplete ``Item`` objects .. literalinclude:: /examples/generated/kotlin/SyncTest.snippet.define-synced-realm.kt :language: kotlin @@ -274,22 +270,22 @@ you can add Sync to your client App. Use the defined configuration to :ref:`open the synced realm `. + When the realm is opened successfully, the initial subscription + query determines which data to sync to the client. + If Development Mode is enabled, App Services automatically + adds any queryable fields based on the query defined in + your schema. - For our example App, we pass our ``config`` object to + For our example app, we pass our ``config`` object to ``realm.open()`` to open a synced realm, then wait for our subscriptions to sync with the backend: .. literalinclude:: /examples/generated/kotlin/SyncTest.snippet.open-synced-realm.kt :language: kotlin - When the realm is opened successfully, the initial subscription - query determines which data to sync to the client. - If Development Mode is enabled, App Services automatically - adds any queryable fields based on the query defined in - your schema. - - For our example App, App Services automatically added the following as - queryable fields based on our initial subscription: + Because we have Development Mode enabled, App Services + automatically added the following as queryable fields based on + our initial subscription: - ``_id`` (always included) - ``ownerId`` @@ -302,9 +298,10 @@ Now that you've open the configured synced realm, you can use it exactly like a non-synced realm. The syntax to :ref:`read `, :ref:`write `, and :ref:`watch for changes ` is identical to the -syntax for non-synced realms. +syntax for non-synced realms. While you work with local data, a +background thread efficiently integrates, uploads, and downloads changesets. -For our example App, we write a new ``List`` and ``Item`` object, +For our example app, we write a new ``List`` and ``Item`` object, then copy them to the synced realm: .. literalinclude:: /examples/generated/kotlin/SyncTest.snippet.write-to-synced-realm.kt @@ -312,8 +309,10 @@ then copy them to the synced realm: The objects successfully sync to Atlas because: -- both objects are within the parameters of the subscription query(the ``List`` is owned by the user, and the ``List`` is incomplete) -- the current user has permission to write data to the backend (the role allows authorized users to read and write all data) +- Both objects are within the parameters of the subscription query + (the ``List`` is owned by the user and the ``Item`` is incomplete). +- The current user has permission to write data to the backend (the role allows + authorized users to read and write all data). Next Steps ---------- diff --git a/source/sdk/kotlin/sync/subscribe.txt b/source/sdk/kotlin/sync/subscribe.txt index f5b0965dd0b..7a54c242a53 100644 --- a/source/sdk/kotlin/sync/subscribe.txt +++ b/source/sdk/kotlin/sync/subscribe.txt @@ -113,7 +113,7 @@ The examples on this page use a data set for a task list app. The two Realm object types are ``Team`` and ``Task``: -.. literalinclude:: /examples/generated/kotlin/SyncTest.snippet.flexible-sync-models.kt +.. literalinclude:: /examples/generated/kotlin/SchemaSync.snippet.flexible-sync-models.kt :language: kotlin The examples on this page also assume you have an authorized user and a