Skip to content

(DOCSP-39530): Consolidate Multi-User Applications page #3323

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

Merged
merged 11 commits into from
Jul 19, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
In the example below, a user with the email ``aimee@example.com`` logs in and
becomes the active user. Later, a user with the email ``elvis@example.com``
logs in and becomes the active user.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To change the active user, call
:dotnet-sdk:`SwitchUser()
<reference/Realms.Sync.App.html#Realms_Sync_App_SwitchUser_Realms_Sync_User_>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
You can check the user's state through the :dotnet-sdk:`User.State
<reference/Realms.Sync.User.html#Realms_Sync_User_State>` property. This
property's value is a :dotnet-sdk:`UserState
<reference/Realms.Sync.UserState.html>` enum whose values indicate
whether the user is ``LoggedOut``, ``LoggedIn``, or ``Removed``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
You can get the current active user through the
:dotnet-sdk:`App.CurrentUser
<reference/Realms.Sync.App.html#Realms_Sync_App_CurrentUser>` property.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To list all users on the device, read the
:dotnet-sdk:`App.AllUsers <reference/Realms.Sync.App.html#Realms_Sync_App_AllUsers>`
property.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
To log out a logged-in user, call :dotnet-sdk:`User.LogOutAsync()
<reference/Realms.Sync.User.html#Realms_Sync_User_LogOutAsync>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To log out and remove the user, call
:dotnet-sdk:`RemoveUserAsync()
<reference/Realms.Sync.App.html#Realms_Sync_App_RemoveUserAsync_Realms_Sync_User_>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
To change the active user, call :flutter-sdk:`app.switchUser()
<realm/App/switchUser.html>` on the ``User`` object you are switching to:
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
You can check the user's state through the :flutter-sdk:`User.state
<realm/User/state.html>` property. This property's value is a
:flutter-sdk:`UserState <realm/UserState.html>` enum whose values indicate
whether the user is ``loggedOut``, ``loggedIn``, or ``removed``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
You can get the current active user through the
:flutter-sdk:`App.currentUser <realm/App/currentUser.html>` property.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To list users on the device, read your app's :flutter-sdk:`App.users
<realm/App/users.html>` property. This provides access to an
`Iterable <https://api.dart.dev/stable/2.17.0/dart-core/Iterable-class.html>`__
that includes all users that have logged in to the client app.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
To log out a logged-in user, call the :flutter-sdk:`user.logOut()
<realm/User/logOut.html>` method.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
To log out and remove the user, pass the ``User`` object to
:flutter-sdk:`app.removeUser() <realm/App/removeUser.html>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
In the example below, a user named Joe logs in and becomes the active user.
Later, a user named Emma logs in and becomes the active user.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To change the active user, call :java-sdk:`App.switchUser()
<io/realm/mongodb/App.html#switchUser(io.realm.mongodb.User)>` with the new
user's ``User`` object.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
You can check the user's state by calling the :java-sdk:`User.getState()
<io/realm/mongodb/User.html#getState()>` method. This
property's value is a :java-sdk:`User.State
<io/realm/mongodb/User.State.html>` enum whose values indicate
whether the user is ``LOGGED_IN``, ``REMOVED``, or ``LOGGED_OUT``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
You can get the current active user by calling the
:java-sdk:`App.currentUser() <io/realm/mongodb/App.html#currentUser()>` method.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
To list all users on the device, call the
:java-sdk:`App.allUsers() <io/realm/mongodb/App.html#allUsers()>` method.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To log the user out, call :java-sdk:`User.logOut()
<io/realm/mongodb/User.html#logOut()>` or :java-sdk:`User.logOutAsync()
<io/realm/mongodb/User.html#logOutAsync(io.realm.mongodb.App.Callback)>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To remove all information about a user from a device,
use :java-sdk:`user.remove() <io/realm/mongodb/User.html#remove-->`
or :java-sdk:`user.removeAsync()
<io/realm/mongodb/User.html#removeAsync-io.realm.mongodb.App.Callback->`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
In the example below, a user with the email ``joe@example.com`` logs in and
becomes the active user. Later, a user with the email ``emma@example.com``
logs in and becomes the active user.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
In the example below, the active user is initially switched to ``user1``
using the :js-sdk:`Realm.App.switchUser() <classes/App.html#switchUser>` method.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noting this since it came up while I was reviewing Omar's PR: links to the JS API docs don't seem to honor the URL anchors (at least, they don't for me). it just lands you at the top of the page every time

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that might be something browser-specific? I use generic Chrome with no extensions and it honors the URL anchors for me.

Later, the active user is switched to ``user2``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
You can check the user's state through the :js-sdk:`User.state
<classes/Realm.User.html#state>` property. This property's value is a
:js-sdk:`UserState <enums/Realm.UserState.html>` enum whose values indicate
whether the user is ``LoggedIn``, ``LoggedOut``, or ``Removed``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
You can get the current active user through the
:js-sdk:`App.currentUser() <classes/Realm.App-1.html#currentUser>` accessor.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
In the example below, a developer prints out all the logged-in users on the
device by looping through :js-sdk:`Realm.App.allUsers
<classes/App.html#allUsers>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
To log out a logged-in user, call the :js-sdk:`User.logOut()
<classes/Realm.User.html#logOut>` method.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
In the example below, the current user is removed from the device using the
:js-sdk:`Realm.App.removeUser() <classes/App.html#removeUser>` method.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
In the following example, Joe logs in to the app and becomes the
active user. Then, Emma logs in and replaces Joe as the active user.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Kotlin does not currently provide a method to switch users.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To check the user state, read the
:kotlin-sync-sdk:`user.state
<io.realm.kotlin.mongodb/-user/-state/index.html>` property. This property is
an enum whose values can be ``LOGGED_OUT``, ``LOGGED_IN``, or ``REMOVED``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
You can get the current active user using :kotlin-sync-sdk:`App.currentUser
<io.realm.kotlin.mongodb/-app/current-user.html>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
You can access a map of all known user accounts that are stored on
the device using the
:kotlin-sync-sdk:`app.allUsers() <io.realm.kotlin.mongodb/-app/all-users.html>`
method. This method returns all users that have logged in to the
client app on a given device regardless of whether they are currently
authenticated (the ``user.state`` is ``LOGGED_IN`` or ``LOGGED_OUT``).

In the following example, the SDK returns both Emma and Joe's
:kotlin-sync-sdk:`user.id <io.realm.kotlin.mongodb/-user/id.html>`:
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
To log out a logged-in user, call the
:kotlin-sync-sdk:`user.logOut() <io.realm.kotlin.mongodb/-user/log-out.html>`
method.

In the following example, Joe is currently logged-in as the current user.
After we log Joe out of the app, we confirm that he is still stored on
the device as a user and that Emma is now the current user:
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
You can actively remove a user, and all information about that user, from
a device using
:kotlin-sync-sdk:`user.remove() <io.realm.kotlin.mongodb/-user/remove.html>`.

In the following example, Emma is the current (and only) logged-in user
on the device. After we remove her, we confirm that Emma is removed from the
device and that there is no current user, as Joe is still logged out:
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
In the example below, a user with the email ``joe@example.com`` logs in and
becomes the active user. Later, a user with the email ``emma@example.com``
logs in and becomes the active user.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You can change the active user with the ``App.switch(to: User)`` method.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q on the code example for this -- is it supposed to include the second half commented out?

let app = App(id: YOUR_APP_SERVICES_APP_ID)

// ... log in ...
// Get another user on the device, for example with `app.allUsers`
let secondUser: User = getSomeOtherUser()

XCTAssertNotEqual(app.currentUser, secondUser)
// assert(app.currentUser != secondUser)

// Switch to another user
// app.switch(to: secondUser)

// The switch-to user becomes the app.currentUser
// XCTAssertEqual(app.currentUser, secondUser)
// assert(app.currentUser == secondUser)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example definitely needs to be updated, and is called out in the Swift follow-up ticket.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To check the user state, read the ``user.state`` property. This property's
value is an :objc-sdk:`RLMUserState <Enums/RLMUserState.html>` enum whose
cases reflect whether the user is logged out, logged in, or removed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
You can get the current active user through the
:objc-sdk:`App.currentUser
<Classes/RLMApp.html#/c:objc(cs)RLMApp(py)currentUser>` property.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
You can access a map of all known user accounts that are stored on
the device through the ``app.allUsers`` property. This property returns all
users that have logged in to the client app on a given device regardless of
whether they are currently authenticated (the ``user.state`` is logged in or
logged out).

In the following example, the SDK returns both Emma and Joe's
:objc-sdk:`user.identifier <Classes/RLMUser.html#/c:objc(cs)RLMUser(py)identifier>`:
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To log out a logged-in user, call the
:swift-sdk:`user.logOut()
<Extensions/User.html#/s:So7RLMUserC10RealmSwiftE6logOut7Combine6FutureCyyts5Error_pGyF>`
method.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
You can actively remove a user, and all information about that user, from
a device using
:swift-sdk:`user.remove()
<Extensions/User.html#/s:So7RLMUserC10RealmSwiftE6remove7Combine6FutureCyyts5Error_pGyF>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.. tabs-drivers::

tabs:
- id: csharp
content: |

.. literalinclude:: /examples/generated/dotnet/MultiUserExamples.snippet.multi-add.cs
:language: csharp

- id: dart
content: |

.. literalinclude:: /examples/generated/flutter/authenticate_users_test.snippet.email-password-credentials.dart
:language: dart

- id: java
content: |

.. literalinclude:: /examples/generated/java/sync/MultipleUsersTest.snippet.add-a-new-user.java
:language: java

- id: java-kotlin
content: |

.. literalinclude:: /examples/generated/java/sync/MultipleUsersTest.snippet.add-a-new-user.kt
:language: kotlin

- id: javascript
content: |

.. literalinclude:: /examples/MultiUser/AddUser/AddUser.js
:language: javascript

- id: kotlin
content: |

.. io-code-block::

.. input:: /examples/generated/kotlin/AuthenticationTest.snippet.add-a-new-user.kt
:language: kotlin

.. output::
:language: console

Successfully logged in. User state: LOGGED_IN. Current user is now: 65133e130075a51f12a9e635
Successfully logged in. User state: LOGGED_IN. Current user is now: 65133e1357aaf22529343c1b

- id: swift
content: |

.. literalinclude:: /examples/generated/code/start/MultipleUsers.snippet.add-user.swift
:language: swift

- id: typescript
content: |

.. literalinclude:: /examples/MultiUser/AddUser/AddUser.ts
:language: typescript
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.. tabs-drivers::

tabs:
- id: csharp
content: |

.. literalinclude:: /examples/generated/dotnet/MultiUserExamples.snippet.multi-switch.cs
:language: csharp

- id: dart
content: |

.. literalinclude:: /examples/generated/flutter/authenticate_users_test.snippet.change-active-user.dart
:language: dart

- id: java
content: |

.. literalinclude:: /examples/generated/java/sync/MultipleUsersTest.snippet.switch-the-active-user.java
:language: java

- id: java-kotlin
content: |

.. literalinclude:: /examples/generated/java/sync/MultipleUsersTest.snippet.switch-the-active-user.kt
:language: kotlin

- id: javascript
content: |

.. literalinclude:: /examples/MultiUser/SwitchUser/SwitchUser.js
:language: javascript

- id: kotlin
content: |

.. literalinclude:: /examples/MissingPlaceholders/api.kt
:language: kotlin
:copyable: false

- id: swift
content: |

.. literalinclude:: /examples/generated/code/start/MultipleUsers.snippet.switch-user.swift
:language: swift

- id: typescript
content: |

.. literalinclude:: /examples/MultiUser/SwitchUser/SwitchUser.ts
:language: typescript
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.. tabs-drivers::

tabs:
- id: csharp
content: |

.. literalinclude:: /examples/MissingPlaceholders/example.cs
:language: csharp
:copyable: false

- id: dart
content: |

.. literalinclude:: /examples/MissingPlaceholders/example.dart
:language: dart
:copyable: false

- id: java
content: |

.. literalinclude:: /examples/MissingPlaceholders/example.java
:language: java
:copyable: false

- id: java-kotlin
content: |

.. literalinclude:: /examples/MissingPlaceholders/example-java-kotlin.kt
:language: kotlin
:copyable: false

- id: javascript
content: |

.. literalinclude:: /examples/MissingPlaceholders/example.js
:language: javascript
:copyable: false

- id: kotlin
content: |

.. literalinclude:: /examples/MissingPlaceholders/example.kt
:language: kotlin
:copyable: false

- id: swift
content: |

.. literalinclude:: /examples/MissingPlaceholders/example.swift
:language: swift
:copyable: false

- id: typescript
content: |

.. literalinclude:: /examples/MissingPlaceholders/example.ts
:language: typescript
:copyable: false
Loading
Loading