Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(DOCSP-31531): NET SDK Migrate PBS to FS updates #2916

Merged
merged 12 commits into from
Aug 1, 2023
20 changes: 11 additions & 9 deletions examples/dotnet/Examples/ClientResetExamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public async Task TestDiscardUnsyncedChangesHandler()
{
// :remove-start:
app = App.Create(myRealmAppId);
user = await app.LogInAsync(Credentials.Anonymous());
user = await app.LogInAsync(Credentials.Anonymous(false));
dacharyc marked this conversation as resolved.
Show resolved Hide resolved
// :remove-end:
var config = new FlexibleSyncConfiguration(user);
config.ClientResetHandler = new DiscardUnsyncedChangesHandler()
Expand All @@ -55,12 +55,17 @@ public async Task TestDiscardUnsyncedChangesHandler()
// Automatic reset failed; handle the reset manually here
}
};

//:remove-start:
config.Schema = new[] { typeof(Examples.Models.Plant) };
//:remove-end:
var realm = await Realm.GetInstanceAsync(config);
try
{
var realm = await Realm.GetInstanceAsync(config);
}
catch (Exception ex)
{
Console.WriteLine($@"Error creating or opening the
realm file. {ex.Message}");
}
// :snippet-end:
await user.LogOutAsync();
}

public async Task TestManualClientReset()
Expand All @@ -85,9 +90,6 @@ public async Task TestManualClientReset()
var fsConfig = new FlexibleSyncConfiguration(fsUser);
fsConfig.ClientResetHandler =
new ManualRecoveryHandler(HandleClientResetError);
//:remove-start:
fsConfig.Schema = new[] { typeof(User) };
//:remove-end:
var fsrealm = await Realm.GetInstanceAsync(fsConfig);
}

Expand Down
88 changes: 88 additions & 0 deletions examples/dotnet/Examples/FlexibleSyncExamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,95 @@ public async Task TestUseFlexibleSync()
// remove all subscriptions, including named subscriptions
realm.Subscriptions.RemoveAll(true);
});
}

[Test]
public async Task TestOpenFSRealm()
{
// :snippet-start: open-fs-realm
// :replace-start: {
// "terms": {
// "Config.FSAppId": "\"myRealmAppId\"",
// "Credentials.Anonymous(false)": "Credentials.Anonymous()"}
// }
var app = App.Create(Config.FSAppId);
var user = await app.LogInAsync(Credentials.Anonymous(false));
Realm realm;

var config = new FlexibleSyncConfiguration(user)
{
PopulateInitialSubscriptions = (realm) =>
{
var allTasks = realm.All<MyTask>();
realm.Subscriptions.Add(allTasks, new SubscriptionOptions { Name = "allTasks" });
}
};
try
{
realm = await Realm.GetInstanceAsync(config);
// :remove-start:
var session = realm.SyncSession;
Assert.NotNull(session);
// :remove-end:
}
catch (Exception ex)
{
Console.WriteLine($@"Error creating or opening the
realm file. {ex.Message}");
}
// :replace-end:
// :snippet-end:
await user.LogOutAsync();
}

[Test]
public async Task TestOpenFSRealmOffline()
{
// :snippet-start: open-fs-realm-offline
// :replace-start: {
// "terms": {
// "Config.FSAppId": "\"myRealmAppId\"",
// "Credentials.Anonymous(false)": "Credentials.Anonymous()"
// }
// }
var app = App.Create(Config.FSAppId);
// :remove-start:
// Another app.CurrentUser was carrying over into this test
// causing issues with opening the FS realm. This resolves the
// test failure but there should probably be stronger cleanup
// between tests to negate the need for this.
if (app.CurrentUser != null) {
await app.RemoveUserAsync(app.CurrentUser);
await app.LogInAsync(Credentials.Anonymous(false));
};
// :remove-end:
Realms.Sync.User user;
FlexibleSyncConfiguration config;
Realm realm;

if (app.CurrentUser == null)
{
// App must be online for user to authenticate
user = await app.LogInAsync(Credentials.Anonymous(false));
config = new FlexibleSyncConfiguration(user);
realm = Realm.GetInstance(config);
// Go on to add or update subscriptions and use the realm
// :remove-start:
var session = realm.SyncSession;
Assert.NotNull(session);
// :remove-end:
}
else
{
// This works whether online or offline
// It requires a user to have been previously authenticated
user = app.CurrentUser;
config = new FlexibleSyncConfiguration(user);
realm = Realm.GetInstance(config);
// Go on to add or update subscriptions and use the realm
}
// :replace-end:
// :snippet-end:
}

[Test]
Expand Down
4 changes: 2 additions & 2 deletions examples/dotnet/Examples/OpenARealmExamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public async Task Setup()
//realm = await Realm.GetInstanceAsync(config);
// :uncomment-end:
}
catch (RealmFileAccessErrorException ex)
catch (Exception ex)
{
Console.WriteLine($@"Error creating or opening the
realm file. {ex.Message}");
Expand All @@ -58,7 +58,7 @@ public async Task Setup()

// :snippet-start: open-synced-realm-synchronously
// :uncomment-start:
// var synchronousRealm = await Realm.GetInstanceAsync(config);
// var synchronousRealm = Realm.GetInstance(config);
// :uncomment-end:
// :snippet-end:

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var app = App.Create("myRealmAppId");
Realms.Sync.User user;
FlexibleSyncConfiguration config;
Realm realm;

if (app.CurrentUser == null)
{
// App must be online for user to authenticate
user = await app.LogInAsync(Credentials.Anonymous());
config = new FlexibleSyncConfiguration(user);
realm = Realm.GetInstance(config);
// Go on to add or update subscriptions and use the realm
}
else
{
// This works whether online or offline
// It requires a user to have been previously authenticated
user = app.CurrentUser;
config = new FlexibleSyncConfiguration(user);
realm = Realm.GetInstance(config);
// Go on to add or update subscriptions and use the realm
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
var app = App.Create("myRealmAppId");
var user = await app.LogInAsync(Credentials.Anonymous());
Realm realm;

var config = new FlexibleSyncConfiguration(user)
{
PopulateInitialSubscriptions = (realm) =>
{
var allTasks = realm.All<MyTask>();
realm.Subscriptions.Add(allTasks, new SubscriptionOptions { Name = "allTasks" });
}
};
try
{
realm = await Realm.GetInstanceAsync(config);
}
catch (Exception ex)
{
Console.WriteLine($@"Error creating or opening the
realm file. {ex.Message}");
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
var synchronousRealm = await Realm.GetInstanceAsync(config);
var synchronousRealm = Realm.GetInstance(config);
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
realm = await Realm.GetInstanceAsync(config);
}
catch (RealmFileAccessErrorException ex)
catch (Exception ex)
{
Console.WriteLine($@"Error creating or opening the
realm file. {ex.Message}");
Expand Down
42 changes: 11 additions & 31 deletions source/sdk/dotnet/sync.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,43 +18,13 @@ Sync Data Between Devices - .NET SDK
Check Upload & Download Progress </sdk/dotnet/sync/sync-progress>
Convert Between Non-Synced Realms and Synced Realms </sdk/dotnet/sync/convert-realm>
Stream Data to Atlas </sdk/dotnet/sync/asymmetric-sync>

Overview
--------
Partition-Based Sync </sdk/dotnet/sync/partition-based-sync>

Atlas Device Sync automatically synchronizes data between client applications and
an :ref:`Atlas App Services backend <realm-cloud>`. When a client
device is online, Sync asynchronously synchronizes data in a
background thread between the device and your backend App.

When you use Sync in your client application, your implementation must match
the Sync Mode you select in your backend App configuration. The Sync Mode
options are:

- Partition-Based Sync
- Flexible Sync

You can only use one Sync Mode for your application. You cannot mix
Partition-Based Sync and Flexible Sync within the same App.

.. seealso::

:ref:`enable-realm-sync`

.. _dotnet-partition-based-sync-fundamentals:

Partition-Based Sync
--------------------

When you select :ref:`Partition-Based Sync <partition-based-sync>` for your
backend App configuration, your client implementation must include a
partition value. This is the value of the :ref:`partition key
<partition-key>` field you select when you configure Partition-Based Sync.

The partition value determines which data the client application can access.

You pass in the partition value when you open a synced realm.

.. _dotnet-flexible-sync-fundamentals:

Flexible Sync
Expand Down Expand Up @@ -84,6 +54,14 @@ To use Flexible Sync in your client application, open a synced realm
with a Flexible Sync configuration. Then, manage subscriptions
to determine which documents to sync.

.. tip::

Device Sync supports two Sync Modes: Flexible Sync, and the older
Partition-Based Sync. If your App Services backend uses Partition-Based
Sync, refer to :ref:`dotnet-partition-based-sync`.

We recommend using Flexible Sync.

Group Updates for Improved Performance
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -98,3 +76,5 @@ In this scenario, you can maximize sync performance by using
:ref:`Data Ingest <dotnet-data-ingest>` to stream
data from the client application to a Flexible Sync-enabled Atlas App Services
App.


50 changes: 15 additions & 35 deletions source/sdk/dotnet/sync/configure-and-open-a-synced-realm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,45 +101,32 @@ With cached credentials, you can:
- Open a synced realm after downloading changes from your App.
This requires the user to have an active internet connection.

.. _dotnet-flexible-sync-open-realm:

Open a Synced Realm with a Flexible Sync Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When you use Flexible Sync, pass the current user to a
:dotnet-sdk:`FlexibleSyncConfiguration <reference/Realms.Sync.FlexibleSyncConfiguration.html>`
object to open a synced realm.

.. literalinclude:: /examples/generated/dotnet-flexible-sync/FlexibleSyncExamples.snippet.open-a-flexible-synced-realm.cs
:language: csharp

.. important:: Flexible Sync Requires a Subscription

You can't use a Flexible Sync realm until you add at least one subscription.
To learn how to add subscriptions, see: :ref:`<dotnet-sync-add-subscription>`.

.. _dotnet-open-a-synced-realm:
.. _dotnet-partition-sync-open-realm:
.. _dotnet-flexible-sync-open-realm:

Open a Partition-Based Sync Realm While Online
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Open a Synced Realm While Online
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The steps for opening a synced realm while online are:

1. Your app code walks the user through :ref:`authenticating <dotnet-authenticate>`.

#. Create a
:dotnet-sdk:`PartitionSyncConfiguration <reference/Realms.Sync.PartitionSyncConfiguration.html>`
object that includes the :ref:`partition name <partition-value>` and
the :dotnet-sdk:`User <reference/Realms.Sync.User.html>` object.
:dotnet-sdk:`FlexibleSyncConfiguration <reference/Realms.Sync.FlexibleSyncConfiguration.html>`
object that includes :dotnet-sdk:`User <reference/Realms.Sync.User.html>`
object.

#. Open a synced realm by calling the
:dotnet-sdk:`GetInstanceAsync() <reference/Realms.Realm.html#Realms_Realm_GetInstanceAsync_Realms_RealmConfigurationBase_System_Threading_CancellationToken_>`
method, passing in the ``PartitionSyncConfiguration`` object.
method.

#. If your FlexibleSyncConfiguration did not contain
:ref:`initial subscriptions <dotnet-initial-subscriptions>`,
:ref:`add a subscription <dotnet-add-subscription-to-set>`.

The following code demonstrates these steps:

.. literalinclude:: /examples/generated/dotnet/OpenARealmExamples.snippet.open-synced-realm.cs
.. literalinclude:: /examples/generated/dotnet-flexible-sync/FlexibleSyncExamples.snippet.open-fs-realm.cs
:language: csharp

In the above example, the code shows how to open the realm *asynchronously*
Expand All @@ -151,15 +138,8 @@ method:
.. literalinclude:: /examples/generated/dotnet/OpenARealmExamples.snippet.open-synced-realm-synchronously.cs
:language: csharp

.. seealso::

:ref:`Partitions <sync-partitions>`

:ref:`Partition Strategies <partition-strategies>`


Open a Partition-Based Sync Realm While Offline
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Open a Synced Realm While Offline
dacharyc marked this conversation as resolved.
Show resolved Hide resolved
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Once a user authenticates, the ``User`` object persists on the device until the
user logs off. This allows your app to
Expand All @@ -171,7 +151,7 @@ The following code shows how to check if there is an existing ``User`` object.
If none is found, it uses the process outlined about to obtain a user. If the
device already has a ``user``, it opens the synced realm with that user:

.. literalinclude:: /examples/generated/dotnet/OpenARealmExamples.snippet.check-if-offline.cs
.. literalinclude:: /examples/generated/dotnet-flexible-sync/FlexibleSyncExamples.snippet.open-fs-realm-offline.cs
:language: csharp

Configuring Timeouts with AppConfiguration
Expand Down
3 changes: 3 additions & 0 deletions source/sdk/dotnet/sync/flexible-sync.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ You must have at least one subscription before you can read from or write
to the realm. You can create one or more initial subscriptions when you
configure Flexible Sync, or you can add subscriptions after initialization.

.. _dotnet-initial-subscriptions:

Bootstrap the Realm with Initial Subscriptions
``````````````````````````````````````````````

Expand All @@ -120,6 +122,7 @@ queries you want to use to bootstrap the realm, as shown in the following exampl
.. literalinclude:: /examples/generated/dotnet/FlexibleSyncExamples.snippet.bootstrap-a-subscription.cs
:language: csharp

.. _dotnet-add-subscription-to-set:

Add a Subscription
``````````````````
Expand Down
Loading
Loading