Authenticate Users
On this page
After you initialize an Atlas app connection, you must authenticate a user with an authentication provider. This page describes how to authenticate App Services App users with Atlas Device SDK. Refer to Authenticate & Manage Users in the App Services documentation for more information.
Atlas App Services provides the following built-in authentication providers to log users in and out of a client app:
Anonymous users
Email/password authentication
API key authentication
OAuth 2.0 through Facebook, Google, and Apple ID
Custom JWT
Custom Function
Upon successful login, App Services begins a user session for the user. App Services manages sessions with access tokens and refresh tokens. The SDK automatically supplies the logic to manage tokens and provide them with requests. For more information on managing user sessions and tokens, refer to Manage User Tokens.
Once you have a logged-in user, you can:
Open a synced database with the user's configuration object
Call an Atlas Function as the logged-in user
Log the user out (refer to the Log a User Out section)
You can also log multiple users in to an app simultaneously on a single device. Refer to Multi-User Applications for more information.
Prerequisites
To authenticate users through Atlas App Services, you must have an App Services App with one or more authentication providers enabled.
To set up an App Services App with authentication providers, complete the following:
Enable and configure one or more authentication providers. For more information, refer to Authentication Providers in the App Services documentation.
Tip
You can enable multiple authentication providers. If a user authenticates using more than one method, you can link the user identities for each method to a single user account.
Register and Create a New User Account
Atlas App Services registers a user differently depending on the authentication provider:
If you are using email/password authentication, users must first register and confirm their email and password before they can authenticate.
If you are using Google, Facebook, Apple, or Custom JWT, registration is handled by these third-party services.
If you are using anonymous authentication, those users do not require registration.
When a user registers or successfully authenticates to your App, Atlas App Services automatically creates a user object, which contains a unique identifier and user state information. You can optionally configure custom user data if your app needs to store additional user data. To learn more about the user object that App Services provides, refer to Read User Metadata in the App Services documentation.
When a user registers or successfully authenticates to your App, Atlas App Services automatically creates a User object, which contains a unique identifier and provider-specific user metadata. You can optionally configure custom user data if your app needs to store additional user data. To learn more about the user object that App Services provides, refer to Read User Metadata in the App Services documentation.
When a user registers or successfully authenticates to your App, Atlas App Services automatically creates a User object, which contains a unique identifier and provider-specific user metadata. You can optionally configure custom user data if your app needs to store additional user data. To learn more about the user object that App Services provides, refer to Read User Metadata in the App Services documentation.
When a user registers or successfully authenticates to your App, Atlas App Services automatically creates a User object, which contains a unique identifier and provider-specific user metadata. You can optionally configure custom user data if your app needs to store additional user data. To learn more about the user object that App Services provides, refer to Read User Metadata in the App Services documentation.
When a user registers or successfully authenticates to your App, Atlas App Services automatically creates a User object, which contains a unique identifier and provider-specific user metadata. You can optionally configure custom user data if your app needs to store additional user data. To learn more about the user object that App Services provides, refer to Read User Metadata in the App Services documentation.
When a user registers or successfully authenticates to your App, Atlas App Services automatically creates a User object, which contains a unique identifier and provider-specific user metadata. You can optionally configure custom user data if your app needs to store additional user data. To learn more about the user object that App Services provides, refer to Read User Metadata in the App Services documentation.
When a user registers or successfully authenticates to your App, Atlas App Services automatically creates a User object, which contains a unique identifier and provider-specific user metadata. You can optionally configure custom user data if your app needs to store additional user data. To learn more about the user object that App Services provides, refer to Read User Metadata in the App Services documentation.
When a user registers or successfully authenticates to your App, Atlas App Services automatically creates a User object, which contains a unique identifier and provider-specific user metadata. You can optionally configure custom user data if your app needs to store additional user data. To learn more about the user object that App Services provides, refer to Read User Metadata in the App Services documentation.
When a user registers or successfully authenticates to your App, Atlas App Services automatically creates a User object, which contains a unique identifier and provider-specific user metadata. You can optionally configure custom user data if your app needs to store additional user data. To learn more about the user object that App Services provides, refer to Read User Metadata in the App Services documentation.
Important
Google and Apple Account Deletion Requirements
Google and Apple require that applications listed through their respective App Stores must give any user who creates an account the option to delete the account. Whether you use an authentication method where you must manually register a user, such as email/password authentication, or one that that automatically creates a user, such as Sign-In with Apple, you must implement user account deletion.
Log In a User
To authenticate and log users in to your App, first instantiate a
credentials
object containing the credentials associated with the authentication provider.
Then, pass it to the login()
function.
Each authentication provider corresponds to a static function
used to instantiate credentials
objects for that authentication provider.
If successful, app::login()
returns a user object. In the event of a failure,
app::login()
throws an exception of type app_error.
To authenticate and log users in to your App, first instantiate a Credentials object containing the credentials associated with the authentication provider. Then, pass it to LogInAsync().
Each authentication provider corresponds to a factory method
used to instantiate Credentials
objects for that authentication provider.
If successful, LogInAsync()
returns a User object. In the event of a failure,
LogInAsync()
throws an exception of type AppException.
Tip
You can get the authentication provider type used to log in a user through the UserIdentity.Provider property. If the user is currently logged out, the most recent provider used to log in the user is returned.
To authenticate and log users in to your App, first instantiate a Credentials object containing the credentials associated with the authentication provider. Then, pass it to App.logIn().
Each authentication provider corresponds to a Credentials
constructor used to instantiate Credentials
objects for that authentication provider.
If successful, App.logIn()
returns a User object. In the event of a failure, App.logIn()
throws an exception of type AppException.
Tip
You can get the authentication provider type used to log in a user through the UserIdentity.provider property. If the user is currently logged out, the most recent provider used to log in the user is returned.
To authenticate and log users in to your App, first instantiate a Credentials object containing the credentials associated with the authentication provider. Then, pass it to App.login() or App.loginAsync().
While the app.login()
method blocks
code execution in the calling thread until the supplied credentials have
either succeeded or failed to authenticate a user, the
app.loginAsync()
method allows execution to continue, handling
success or failure with a callback function that is guaranteed to
execute on the same thread that called app.loginAsync()
.
Each authentication provider corresponds to a static helper method used to instantiate Credentials
objects for that authentication provider.
If successful, App.login()
returns a User
object. In the event of a failure, App.login()
throws an
exception of type AppException.
Pass a callback to the App.loginAsync()
method to handle success or
failure. This callback accepts a single parameter of type
App.Result
. The isSuccess()
method of the App.Result
object
passed to the callback returns a boolean that indicates whether the
operation succeeded. In the event of a failure, you can view the
error that caused the failure using the getError()
method.
Tip
You can get the authentication provider type used to log in a user through the UserIdentity.getProvider() method. If the user is currently logged out, the most recent provider used to log in the user is returned.
To authenticate and log users in to your App, first instantiate a Credentials object containing the credentials associated with the authentication provider. Then, pass it to App.logIn().
Each authentication provider corresponds to a Credentials
method used to instantiate Credentials
objects for that authentication provider.
If successful, App.logIn()
returns a User object. In the event of a failure, App.logIn()
throws an exception.
Tip
You can get the authentication provider type used to log in a user through the UserIdentity.providerType. If the user is currently logged out, the most recent provider used to log in the user is returned.
To authenticate and log users in to your App, first instantiate a Credentials object containing the credentials associated with the authentication provider. Then, pass it to app.login().
Each authentication provider corresponds to a static helper method
used to instantiate Credentials
objects for that authentication provider.
If successful, app.login()
returns a User object. In the event of a failure,
app.login()
throws one of three exception types, depending on the error:
AuthException: the top-level or "catch-all" for problems related to user account actions. Prefer catching sub-types for granular error handling.
InvalidCredentialsException: the provided credentials were not correct. Only email/password, API Key, and JWT providers can throw this exception. Other providers throw
AuthException
.ServiceException: the top-level or "catch-all" for problems related to HTTP requests made to App Services. This covers HTTP transport problems, problems passing JSON, or the server considering the request invalid. Prefer catching sub-types for more granular error handling.
Tip
You can get the authentication provider type used to log in a user through the UserIdentity.provider property. If the user is currently logged out, the most recent provider used to log in the user is returned.
To authenticate and log users in to your App, first instantiate a Credentials object containing the credentials associated with the authentication provider. Then, pass it to App.login() or App.loginAsync().
While the app.login()
method blocks
code execution in the calling thread until the supplied credentials have
either succeeded or failed to authenticate a user, the
app.loginAsync()
method allows execution to continue, handling
success or failure with a callback function that is guaranteed to
execute on the same thread that called app.loginAsync()
.
Each authentication provider corresponds to a static helper method used to instantiate Credentials
objects for that authentication provider.
If successful, App.login()
returns a User
object. In the event of a failure, App.login()
throws an
exception of type AppException.
Pass a callback to the App.loginAsync()
method to handle success or
failure. This callback accepts a single parameter of type
App.Result
. The isSuccess()
method of the App.Result
object
passed to the callback returns a boolean that indicates whether the
operation succeeded. In the event of a failure, you can view the
error that caused the failure using the getError()
method.
Tip
You can get the authentication provider type used to log in a user through the UserIdentity.getProvider() method. If the user is currently logged out, the most recent provider used to log in the user is returned.
Async/Await
New in version 10.15.0.
The async/await version of the App.login method asynchronously returns a User or Error.
func login() async { do { let app = App(id: YOUR_APP_SERVICES_APP_ID) // Authenticate with the instance of the app that points // to your backend. Here, we're using anonymous login. let user = try await app.login(credentials: Credentials.anonymous) print("Successfully logged in user: \(user)") } catch { print("Failed to log in user: \(error.localizedDescription)") } }
Starting with Swift SDK Versions 10.15.0 and 10.16.0, many of the SDK's APIs support the Swift async/await syntax. Projects must meet these requirements:
Swift SDK Version | Swift Version Requirement | Supported OS |
---|---|---|
10.25.0 | Swift 5.6 | iOS 13.x |
10.15.0 or 10.16.0 | Swift 5.5 | iOS 15.x |
If your app accesses the SDK in an async/await
context, mark the code
with @MainActor
to avoid threading-related crashes.
Callback
To authenticate and log users in to your App, first instantiate a Credentials object containing the credentials associated with the authentication provider. Then, pass it to App.logIn().
Each authentication provider corresponds to a Credentials helper
method used to instantiate Credentials
objects for that authentication provider.
If successful, App.login()
returns a User object. In the event of a failure, App.login()
throws an exception of type AppError, which is a type alias for the
underlying RLMAppError.
To authenticate and log users in to your App, first instantiate a Credentials object containing the credentials associated with the authentication provider. Then, pass it to App.logIn().
Each authentication provider corresponds to a Credentials
method used to instantiate Credentials
objects for that authentication provider.
If successful, App.logIn()
returns a User object. In the event of a failure, App.logIn()
throws an exception.
Tip
You can get the authentication provider type used to log in a user through the UserIdentity.providerType. If the user is currently logged out, the most recent provider used to log in the user is returned.
auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); auto user = app.login(realm::App::credentials::anonymous()).get();
var user = await app.LogInAsync(Credentials.Anonymous());
final anonUser = await app.logIn(Credentials.anonymous()); final otherAnonUser = await app.logIn(Credentials.anonymous(reuseCredentials: false));
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); Credentials anonymousCredentials = Credentials.anonymous(); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(anonymousCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated anonymously."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
// Create an anonymous credential const credentials = Realm.Credentials.anonymous(); const user = await app.logIn(credentials);
// Instantiate your App Services App val app = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { // Log in the user with the credentials associated // with the authentication provider // If successful, returns an authenticated `User` object val user = app.login(credentials) // ... work with the user ... }
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val anonymousCredentials: Credentials = Credentials.anonymous() var user: User? app.loginAsync(anonymousCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated anonymously.") user = app.currentUser() } else { Log.e("AUTH", it.error.toString()) } }
let anonymousCredentials = Credentials.anonymous app.login(credentials: anonymousCredentials) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
// Create an anonymous credential const credentials = Realm.Credentials.anonymous(); const user = await app.logIn(credentials);
Anonymous
Anonymous authentication enables users to log in to your application with short-term accounts that store no persistent personal information. You might use this to allow users to try your app before they sign up for an account or while developing and testing your app. Anonymous users do not require registration. Refer to Anonymous Authentication in the App Services documentation for more information.
To log in with anonymous
authentication, create an anonymous credential by calling
Credentials.anonymous()
and then pass the generated credential to
app.logIn
.
final anonCredentials = Credentials.anonymous(); await app.logIn(anonCredentials);
If you want more than one anonymous user, set reuseCredentials: false
when creating additional anonymous credentials.
To log in with anonymous
authentication, create an anonymous credential by calling
Credentials.anonymous()
and then pass the generated credential to
app.login()
or app.loginAsync()
.
To log in, create an anonymous credential and pass it to App.logIn()
:
To log in with anonymous authentication, create an anonymous credential by calling Credentials.anonymous(), and then pass the generated credential to app.login():
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { val anonymousCredentials = Credentials.anonymous() val user = app.login(anonymousCredentials) }
By default, the Kotlin SDK reuses the same anonymous user
if that user has not logged out. If you want to create more than
one anonymous user, set reuseExisting = false
when logging in
with additional anonymous credentials:
To log in with anonymous
authentication, create an anonymous credential by calling
Credentials.anonymous()
and then pass the generated credential to
app.login()
or app.loginAsync()
.
To authenticate and log users in to your App, first instantiate a Credentials object containing the credentials associated with the authentication provider. Then, pass it to App.logIn().
Each authentication provider corresponds to a Credentials
method used to instantiate Credentials
objects for that authentication provider.
If successful, App.logIn()
returns a User object. In the event of a failure, App.logIn()
throws an exception.
Tip
You can get the authentication provider type used to log in a user through the UserIdentity.providerType. If the user is currently logged out, the most recent provider used to log in the user is returned.
auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); auto user = app.login(realm::App::credentials::anonymous()).get();
var user = await app.LogInAsync(Credentials.Anonymous());
final anonUser = await app.logIn(Credentials.anonymous()); final otherAnonUser = await app.logIn(Credentials.anonymous(reuseCredentials: false));
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); Credentials anonymousCredentials = Credentials.anonymous(); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(anonymousCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated anonymously."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
// Create an anonymous credential const credentials = Realm.Credentials.anonymous(); const user = await app.logIn(credentials);
// Logs in with an anonymous user val anonUser = app.login(Credentials.anonymous()) // Logs in with a new, different anonymous user val otherAnonUser = app.login(Credentials.anonymous(reuseExisting = false))
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val anonymousCredentials: Credentials = Credentials.anonymous() var user: User? app.loginAsync(anonymousCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated anonymously.") user = app.currentUser() } else { Log.e("AUTH", it.error.toString()) } }
let anonymousCredentials = Credentials.anonymous app.login(credentials: anonymousCredentials) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
// Create an anonymous credential const credentials = Realm.Credentials.anonymous(); const user = await app.logIn(credentials);
Email/Password
The email/password authentication provider enables users to log in to your application with an email username and a password. Refer to Email/Password Authentication in the App Services documentation for more information.
Important
Email/Password Users Require Registration
Email/password authentication requires that you register and then confirm the user-provided email and password before the user can authenticate to an App Services App. Learn how to register email/password users.
To log in with email/password authentication, create an
email/password credential by calling Credentials.emailPassword()
with the user's email and password.
Then pass the credential to app.logIn
.
To log in with email/password authentication, create an
email/password credential by calling Credentials.emailPassword()
with the user's email and password. Then pass the generated credential
to app.login()
or app.loginAsync()
.
To log in, create an email/password credential with the user's email address and
password and pass it to App.logIn()
:
To log in with email/password authentication, create an email/password credential by calling Credentials.emailPassword() with the user's registered email and password, and then pass the generated credential to app.login():
To log in with email/password authentication, create an
email/password credential by calling Credentials.emailPassword()
with the user's email and password. Then pass the generated credential
to app.login()
or app.loginAsync()
.
To log in, create an email/password credential with the user's email address and
password and pass it to App.logIn()
:
auto user = app.login(realm::App::credentials::username_password( userEmail, userPassword)) .get();
var user = await app.LogInAsync( Credentials.EmailPassword("caleb@mongodb.com", "MySekritPwd"));
final emailPwCredentials = Credentials.emailPassword("lisa@example.com", "myStr0ngPassw0rd"); await app.logIn(emailPwCredentials);
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); Credentials emailPasswordCredentials = Credentials.emailPassword("<email>", "<password>"); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(emailPasswordCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated using an email and password."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
// Create an email/password credential const credentials = Realm.Credentials.emailPassword( "someone@example.com", "Pa55w0rd!" ); const user = await app.logIn(credentials);
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { val emailPasswordCredentials = Credentials.emailPassword(email, password) val user = app.login(emailPasswordCredentials) }
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val emailPasswordCredentials: Credentials = Credentials.emailPassword( "<email>", "<password>" ) var user: User? = null app.loginAsync(emailPasswordCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated using an email and password.") user = app.currentUser() } else { Log.e("AUTH", it.error.toString()) } }
let email = "skroob@example.com" let password = "12345" app.login(credentials: Credentials.emailPassword(email: email, password: password)) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
// Create an email/password credential const credentials = Realm.Credentials.emailPassword( "someone@example.com", "Pa55w0rd!" ); const user = await app.logIn(credentials);
Custom JWT
The Custom JWT authentication provider enables users to log in to your application with a custom JSON Web Token (JWT). Registration for JWT authentication is handled by the JWT provider. Refer to Custom JWT Authentication in the App Services documentation for more information.
To log in with Custom JWT authentication, create a JWT credential by calling
Credentials.jwt()
on a JWT string. Then pass the credential to app.logIn
.
To log in with custom JWT authentication, create a
custom JWT credential by calling Credentials.jwt()
with your custom JWT. Then pass the generated credential
to app.login()
or app.loginAsync()
.
To log in, create a Custom JWT credential with a JWT from the external system
and pass it to App.logIn()
:
To log in with JWT authentication, create a JWT credential by calling Credentials.jwt() with the user's JWT, and then pass the generated credential to app.login():
To log in with custom JWT authentication, create a
custom JWT credential by calling Credentials.jwt()
with your custom JWT. Then pass the generated credential
to app.login()
or app.loginAsync()
.
To log in, create a Custom JWT credential with a JWT from the external system
and pass it to App.logIn()
:
auto token = "<jwt>"; auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); auto user = app.login(realm::App::credentials::custom(token)).get();
var user = await app.LogInAsync(Credentials.JWT(jwt_token));
final token = await authenticateWithExternalSystem(); final jwtCredentials = Credentials.jwt(token); final currentUser = await app.logIn(jwtCredentials);
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); // fetch JWT from custom provider Credentials customJWTCredentials = Credentials.jwt("<token>"); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(customJWTCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated using a custom JWT."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
// Create a custom jwt credential const jwt = await authenticateWithExternalSystem(); const credentials = Realm.Credentials.jwt(jwt); const user = await app.logIn(credentials);
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { // Registration is handled by the JWT provider val jwtCredentials = Credentials.jwt(jwtToken) val user = app.login(jwtCredentials) }
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) // fetch JWT from custom provider val customJWTCredentials: Credentials = Credentials.jwt("<token>") var user: User? = null app.loginAsync(customJWTCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated using a custom JWT.") user = app.currentUser() } else { Log.e("AUTH", "Error logging in: ${it.error.toString()}") } }
let credentials = Credentials.jwt(token: "<jwt>") app.login(credentials: credentials) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
// Create a custom jwt credential. const jwt = await authenticateWithExternalSystem(); const credentials = Realm.Credentials.jwt(jwt); const user = await app.logIn(credentials);
API Key
The API Key authentication provider enables authenticated non-anonymous users to log in to your application with an API key. Refer to API Key Authentication in the App Services documentation for more information.
User API keys are generated automatically and managed by the SDK. Learn how to Manage User API Keys.
To log in with API key authentication, create an ApiKey
credential by calling Credentials.apiKey()
on an API key string. Then pass the credential to app.logIn()
.
To log in with API Key authentication, create an
API Key credential by calling Credentials.apiKey()
with an API Key. Then pass the generated credential
to app.login()
or app.loginAsync()
.
To log in with an API key, create an API Key credential with a server or user
API key and pass it to App.logIn()
:
To log in with API key authentication, create an API Key credential by calling Credentials.apiKey() with the user's API key, and then passing the generated credential to app.login():
To log in with API Key authentication, create an
API Key credential by calling Credentials.apiKey()
with an API Key. Then pass the generated credential
to app.login()
or app.loginAsync()
.
To log in with an API key, create an API Key credential with a server or user
API key and pass it to App.logIn()
:
auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); auto user = app.login(realm::App::credentials::api_key(API_KEY)).get();
var user = await app.LogInAsync(Credentials.ApiKey(apiKey));
final apiKeyCredentials = Credentials.apiKey(myApiKey); final apiKeyUser = await app.logIn(apiKeyCredentials);
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); Credentials apiKeyCredentials = Credentials.apiKey("<key>"); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(apiKeyCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated using an API Key."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
// Get the API key from the local environment const apiKey = process.env?.appServicesApiKey; if (!apiKey) { throw new Error("Could not find a Server API Key."); } // Create an api key credential const credentials = Realm.Credentials.apiKey(apiKey); const user = await app.logIn(credentials);
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { val user = app.login(Credentials.apiKey(key)) }
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val apiKeyCredentials: Credentials = Credentials.apiKey("<key>") var user: User? = null app.loginAsync(apiKeyCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated using an API Key.") user = app.currentUser() } else { Log.e("AUTH", "Error logging in: ${it.error.toString()}") } }
let credentials = Credentials.userAPIKey("<api-key>") app.login(credentials: credentials) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
// Get the API key from the local environment. const apiKey = process.env?.appServicesApiKey; if (!apiKey) { throw new Error("Could not find a Server API Key."); } // Create an api key credential. const credentials = Realm.Credentials.apiKey(apiKey); const user = await app.logIn(credentials);
Custom Function
The Custom Function authentication provider enables users to log in to your application using custom authentication logic handled by an Atlas Function. Refer to Custom Function Authentication in the App Services documentation for more information.
To log in with Custom Function authentication, pass a stringified JSON with
your custom arguments to Credentials.function().
Then pass the credential to app.logIn
.
To log in with custom function authentication, create a credential by calling
Credentials.customFunction()
. The customFunction() method expects a
Document that contains the properties and values used by the Atlas auth function.
For example, suppose the backend function expects the input parameter to include
a field named username
, like this:
exports = async function(loginPayload) { const { username } = loginPayload; ... }
The document you pass to Credentials.customFunction()
might look like this:
Document("username", "bob")
You then pass the generated credential to app.login()
or app.loginAsync()
.
To log in with the custom function provider, create a Custom Function credential
with a payload object and pass it to App.logIn()
:
To log in with Custom Function authentication, pass your custom arguments as a payload to Credentials.customFunction(), and then pass the generated credential to app.login().
New in version 1.9.0.
You can serialize data for a Custom Function credential using an EJSON encoder. For more information, including examples, refer to Serialization.
To log in with custom function authentication, create a credential by calling
Credentials.customFunction()
. The customFunction() method expects a
Document that contains the properties and values used by the Atlas auth function.
For example, suppose the backend function expects the input parameter to include
a field named username
, like this:
exports = async function(loginPayload) { const { username } = loginPayload; ... }
The document you pass to Credentials.customFunction()
might look like this:
Document("username", "bob")
You then pass the generated credential to app.login()
or app.loginAsync()
.
To log in with the custom function provider, create a Custom Function credential
with a payload object and pass it to App.logIn()
:
auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); /* Custom function authentication takes a string parameters argument. The parameter details vary depending on how you define your custom authentication function. */ std::string params = "{\"username\": \"bob\"}"; auto user = app.login(realm::App::credentials::function(params)).get();
var functionParameters = new { username = "caleb", password = "MySekritPwd", IQ = 42, hasPets = true }; var user = await app.LogInAsync(Credentials.Function(functionParameters));
final credentials = { "username": "someUsername", }; // payload must be a JSON-encoded string final payload = jsonEncode(credentials); final customCredentials = Credentials.function(payload); final currentUser = await app.logIn(customCredentials);
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID).build()); Credentials customFunctionCredentials = Credentials.customFunction(new org.bson.Document("username", "bob")); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(customFunctionCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated using a custom function."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
// Create a custom function credential const credentials = Realm.Credentials.function({ username: "ilovemongodb", }); const user = await app.logIn(credentials);
// Create custom arguments for your Atlas Function val customCredentials = Credentials.customFunction( payload = mapOf("username" to "bob") ) val user = app.login(customCredentials)
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val customFunctionCredentials: Credentials = Credentials.customFunction(org.bson.Document("username", "bob")) var user: User? = null app.loginAsync(customFunctionCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated using a custom function.") user = app.currentUser() } else { Log.e("AUTH", "Error logging in: ${it.error.toString()}") } }
let params: Document = ["username": "bob"] app.login(credentials: Credentials.function(payload: params)) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
// Create a custom function credential. const credentials = Realm.Credentials.function({ username: "ilovemongodb", }); const user = await app.logIn(credentials);
The Google authentication provider allows you to authenticate users through their existing Google account using an OAuth 2.0 token. Refer to Google Authentication in the App Services documentation for more information.
Before you can authenticate users with Google, you must set up your application for Google User authentication:
In the Google Cloud Platform console, create an OAuth 2.0 client ID of type "Web application".
Configure your backend App to use that client ID and the associated client secret.
Enable OpenID Connect on the backend.
To log in with a Google authentication code, pass a Google authentication code to credentials::google_auth_code().
auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); // The user's server auth code you got from Google auto myAuthCode = "auth_code_from_google"; auto user = app.login(realm::App::credentials::google_auth_code(myAuthCode)).get();
To log in with a Google ID token, pass a Google ID token to credentials::google_id_token().
To log in with a Google authentication code, pass a Google authentication code to
Credentials.googleAuthCode().
Then pass the credential to app.logIn
.
final googleAuthCodeCredentials = Credentials.googleAuthCode(authCode); final currentUser = await app.logIn(googleAuthCodeCredentials);
To log in with a Google ID token, pass a Google ID token to
Credentials.googleIdToken().
Then pass the credential to app.logIn
.
Use Google's official Sign-In for Android to authenticate Google users in your Android application:
Note
Code Example Below
For an implementation of these instructions, check out the code block below.
Add the Google Sign-In for Android dependency to the
dependencies
block of your application levelbuild.gradle
:com.google.android.gms:play-services-auth:19.2.0 Create a GoogleSignInOptions with the following builder options:
an ID token request -- pass your OAuth 2.0 client ID as the
serverClientId
.
Use the
GoogleSignInOptions
to create aGoogleSignInClient
with GoogleSignIn.getClient()Use the
GoogleSignInClient
to create anIntent
capable of triggering Google Sign-In.Use registerForActivityResult() to configure a callback. Your callback should use GoogleSignIn.getSignedInAccountFromIntent() to access the result of Google Sign-In: a
Task<GoogleSignInAccount>
.Use the launch() method of the ActivityResultLauncher returned in the previous step to start Google Sign-In. Pass the
launch()
method your Google Sign-InIntent
.Use
isSuccessful()
to handle Google Sign-In errors.Access the result of the task (a GoogleSignInAccount) with
getResult()
.Access the ID token for the
GoogleSignInAccount
withgetIdToken()
.Create a Realm
Credentials
object with Credentials.google(). Pass the ID token as the first parameter, and GoogleAuthType.ID_TOKEN as the second parameter.Use the app.loginAsync() or app.login() methods to authenticate with the Atlas App Services backend using the token.
Tip
See also:
To learn more about Google Sign-In for Android, check out the official Google Sign-In for Android Integration Guide.
The following code implements this flow, starting with a method call to
loginWithGoogle()
:
Example
Authenticate with Google on a Node.js Server
Refer to the code for an example Node.js server
that implements Sign in With Google.
All of the Google OAuth 2.0 implementation is in the server.js
file.
The example uses Express for routing and the Google Auth Library for Node.js.
You might want to authenticate with Google on a Node.js server to perform server-side operations on behalf of a user, like call an Atlas Function with a user's credentials.
Use the official Google Auth Library for Node.js to handle the user authentication and redirect flow from a Node.js client application:
Install the Realm and Google APIs npm packages.
npm install realm googleapis Import the packages into your project.
const Realm = require("realm"); const { google } = require("googleapis"); Create configuration for Google OAuth 2.0 client and the SDK.
// Configure and instantiate Google OAuth2.0 client const oauthConfig = { client_id: GOOGLE_CLIENT_ID, project_id: GOOGLE_PROJECT_ID, auth_uri: "https://accounts.google.com/o/oauth2/auth", token_uri: "https://oauth2.googleapis.com/token", auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs", client_secret: GOOGLE_CLIENT_SECRET, redirect_uris: [`${BASE_URL}/auth/google/callback`], JWTsecret: "secret", scopes: [ "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", "openid", // any other scopes you might require. View all here - https://developers.google.com/identity/protocols/oauth2/scopes ], }; const OAuth2 = google.auth.OAuth2; const oauth2Client = new OAuth2( oauthConfig.client_id, oauthConfig.client_secret, oauthConfig.redirect_uris[0] ); // Instantiate Realm app const realmApp = new Realm.App({ id: REALM_APP_ID, }); Generate an OAuth login link, and pass it to the application client.
// generate OAuth 2.0 log in link const loginLink = oauth2Client.generateAuthUrl({ access_type: "offline", // Indicates that we need to be able to access data continuously without the user constantly giving us consent scope: oauthConfig.scopes, }); Process the request from the the Google authentication server, which includes an access code in the query string using the Google OAuth 2.0 client's
getToken()
method. In the callback function, sign in to your App using theid_token
.
Use Google's official Sign-In for Android
to authenticate Google users in your Android application. The following
code implements this flow, starting with a method call to
loginWithGoogle()
.
Tip
To learn more about Google Sign-In for Android, check out the official Google Sign-In for Android Integration Guide.
Kotlin Multiplatform (KMP) supports many environments, but this example shows sign-in on the Android platform. For information about signing into a Google account on Apple platforms, switch the language selector on this page to Swift.
Use Google's official Sign-In for Android to authenticate Google users in your Android application:
Note
Code Example Below
For an implementation of these instructions, check out the code block below.
Add the Google Sign-In for Android dependency to the
dependencies
block of your application levelbuild.gradle
:com.google.android.gms:play-services-auth:19.2.0 Create a GoogleSignInOptions with the following builder options:
an ID token request -- pass your OAuth 2.0 client ID as the
serverClientId
.
Use the
GoogleSignInOptions
to create aGoogleSignInClient
with GoogleSignIn.getClient()Use the
GoogleSignInClient
to create anIntent
capable of triggering Google Sign-In.Use registerForActivityResult() to configure a callback. Your callback should use GoogleSignIn.getSignedInAccountFromIntent() to access the result of Google Sign-In: a
Task<GoogleSignInAccount>
.Use the launch() method of the ActivityResultLauncher returned in the previous step to start Google Sign-In. Pass the
launch()
method your Google Sign-InIntent
.Use
isSuccessful()
to handle Google Sign-In errors.Access the result of the task (a GoogleSignInAccount) with
getResult()
.Access the ID token for the
GoogleSignInAccount
withgetIdToken()
.Create a Realm
Credentials
object with Credentials.google(). Pass the ID token as the first parameter, and GoogleAuthType.ID_TOKEN as the second parameter.Use the app.loginAsync() or app.login() methods to authenticate with the Atlas App Services backend using the token.
Tip
See also:
To learn more about Google Sign-In for Android, check out the official Google Sign-In for Android Integration Guide.
The following code implements this flow, starting with a method call to
loginWithGoogle()
:
Follow the official Google Sign-In for iOS Integration Guide to set up the authentication flow for your application. In the sign-in completion handler, create an App Services Google credential and log the user into your App Services app.
The value that you pass to the credential depends on whether or not you have enabled OpenID Connect for the provider:
If OpenID Connect is enabled, pass the
id_token
included in the Google OAuth response to Credentials.googleId(token:).If OpenID Connect is not enabled, pass the user's server auth code to Credentials.google(serverAuthCode:).
The documentation does not contain a TypeScript example for authentication with Google.
Instead, refer to the JavaScript example. Select JavaScript from the programming language selector on this page to see the JavaScript example.
auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); // The user's OpenID Connect id_token you got from the Google OAuth response auto myIdToken = "open_id_connect_id_token_from_google"; auto user = app.login(realm::App::credentials::google_id_token(myIdToken)).get();
var user = await app.LogInAsync(Credentials.Google(googleAuthCode, GoogleCredentialType.AuthCode));
final googleIdTokenCredentials = Credentials.googleIdToken(idToken); final currentUser = await app.logIn(googleIdTokenCredentials);
private void signInWithGoogle() { GoogleSignInOptions gso = new GoogleSignInOptions .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("YOUR WEB APPLICATION CLIENT ID FOR GOOGLE AUTH") .build(); GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, gso); Intent signInIntent = googleSignInClient.getSignInIntent(); ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { public void onActivityResult(ActivityResult result) { Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(result.getData()); handleSignInResult(task); } }); resultLauncher.launch(signInIntent); } private void handleSignInResult(Task<GoogleSignInAccount> completedTask) { try { if (completedTask.isSuccessful()) { GoogleSignInAccount account = completedTask.getResult(ApiException.class); String token = account.getIdToken(); Credentials googleCredentials = Credentials.google(token, GoogleAuthType.ID_TOKEN); app.loginAsync(googleCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully logged in to MongoDB Realm using Google OAuth."); } else { Log.e("AUTH", "Failed to log in to MongoDB Realm: ", it.getError()); } }); } else { Log.e("AUTH", "Google Auth failed: " + completedTask.getException().toString()); } } catch (ApiException e) { Log.w("AUTH", "Failed to log in with Google OAuth: " + e.getMessage()); } }
// Get Google token and use it to sign into Realm oauth2Client.getToken(authCodeFromQueryString, async function ( error, token ) { if (error) return errorHandler(error); try { const credential = Realm.Credentials.google({ idToken: token.id_token, }); const user = await realmApp.logIn(credential); console.log("signed in as Realm user", user.id); } catch (error) { errorHandler(error); } });
fun loginWithGoogle() { val gso = GoogleSignInOptions .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("YOUR WEB APPLICATION CLIENT ID FOR GOOGLE AUTH") .build() val googleSignInClient = GoogleSignIn.getClient(activity, gso) val signInIntent: Intent = googleSignInClient.signInIntent val resultLauncher: ActivityResultLauncher<Intent> = // Note: this activity MUST inherit from ComponentActivity or AppCompatActivity to use this API registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> val task: Task<GoogleSignInAccount> = GoogleSignIn.getSignedInAccountFromIntent(result.data) handleSignInResult(task) } resultLauncher.launch(signInIntent) } fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) { try { if (completedTask.isSuccessful) { val account: GoogleSignInAccount? = completedTask.getResult(ApiException::class.java) val token: String = account?.idToken!! val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { val user = app.login(Credentials.google(token, GoogleAuthType.ID_TOKEN)) } } else { Log.e("AUTH", "Google Auth failed: ${completedTask.exception}") } } catch (e: ApiException) { Log.e("AUTH", "Failed to authenticate using Google OAuth: " + e.message); } }
fun loginWithGoogle() { val gso = GoogleSignInOptions .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("YOUR WEB APPLICATION CLIENT ID FOR GOOGLE AUTH") .build() val googleSignInClient = GoogleSignIn.getClient(this, gso) val signInIntent: Intent = googleSignInClient.signInIntent val resultLauncher: ActivityResultLauncher<Intent> = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> val task: Task<GoogleSignInAccount> = GoogleSignIn.getSignedInAccountFromIntent(result.data) handleSignInResult(task) } resultLauncher.launch(signInIntent) } fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) { try { if (completedTask.isSuccessful) { val account: GoogleSignInAccount? = completedTask.getResult(ApiException::class.java) val token: String = account?.idToken!! val googleCredentials: Credentials = Credentials.google(token, GoogleAuthType.ID_TOKEN) app.loginAsync(googleCredentials) { if (it.isSuccess) { Log.v( "AUTH", "Successfully logged in to MongoDB Realm using Google OAuth." ) } else { Log.e("AUTH", "Failed to log in to MongoDB Realm", it.error) } } } else { Log.e("AUTH", "Google Auth failed: ${completedTask.exception}") } } catch (e: ApiException) { Log.e("AUTH", "Failed to authenticate using Google OAuth: " + e.message); } }
ID Token
func sign(_ signIn: GIDSignIn!, didSignInFor googleUser: GIDGoogleUser!, withError error: Error!) { if let error = error { print("\(error.localizedDescription)") return } // Get the ID token for the authenticated user so you can pass it to Realm let idToken = googleUser.authentication.idToken! let credentials = Credentials.googleId(token: idToken) app.login(credentials: credentials) { result in DispatchQueue.main.async { switch result { case .failure(let error): print("Failed to log in to MongoDB Realm: \(error)") case .success(let user): print("Successfully logged in to MongoDB Realm using Google OAuth.") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } } } }
Server Auth Code
func sign(_ signIn: GIDSignIn!, didSignInFor googleUser: GIDGoogleUser!, withError error: Error!) { if let error = error { print("\(error.localizedDescription)") return } // Upon first successful sign-in, forward serverAuthCode credentials to MongoDB Realm. // Upon subsequent sign-ins, this returns nil. let credentials = Credentials.google(serverAuthCode: googleUser.serverAuthCode!) app.login(credentials: credentials) { result in DispatchQueue.main.async { switch result { case .failure(let error): print("Failed to log in to MongoDB Realm: \(error)") case .success(let user): print("Successfully logged in to MongoDB Realm using Google OAuth.") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } } } }
// The documentation does not currently have this code example in TypeScript. // Please refer to the other languages or related pages for example code.
The Facebook authentication provider allows you to authenticate users through a Facebook app using their existing Facebook account. Refer to Facebook Authentication in the App Services documentation for more information.
Important
Do Not Store Facebook Profile Picture URLs
Facebook profile picture URLs include the user's access token to grant permission to the image. To ensure security, do not store a URL that includes a user's access token. Instead, access the URL directly from the user's metadata fields when you need to fetch the image.
To log in with Facebook authentication, pass a Facebook access token to
Credentials.facebook().
Then pass the credential to app.logIn
.
Follow the official Facebook Login for Android Quickstart to set up the authentication flow for your application. In the login completion handler, get the logged in user's access token from the Facebook LoginResult. Use the access token to create a Facebook credential for Atlas Device SDK, and then log the user into your app.
You can use the official Facebook SDK to handle the user authentication and redirect flow from a client application. Once authenticated, the Facebook SDK returns an access token that you can send to your app and use to finish logging the user in to your app.
Before you can authenticate users with Facebook, you must set up the authentication flow for your application by following the official Facebook Login for Android Quickstart.
In the login completion handler, get the logged in user's access token from the Facebook LoginResult. Use the access token to create a Facebook credential by calling Credentials.facebook() with the user's access token, and then pass the generated credential to app.login().
Important
Do Not Store Facebook Profile Picture URLs
Facebook profile picture URLs include the user's access token to grant permission to the image. To ensure security, do not store a URL that includes a user's access token. Instead, access the URL directly from the user's metadata fields when you need to fetch the image.
Kotlin Multiplatform (KMP) supports many environments, but this example shows sign-in on the Android platform. For information about signing into a Facebook account on Apple platforms, switch the language selector on this page to Swift.
Follow the official Facebook Login for Android Quickstart to set up the authentication flow for your application. In the login completion handler, get the logged in user's access token from the Facebook LoginResult. Use the access token to create a Facebook credential for Atlas Device SDK, and then log the user into your app.
Follow the official Facebook Login for iOS Quickstart to set up the authentication flow for your application. In the login completion handler, create an App Services Facebook credential with the logged in user's access token string and log the user into your App Services app.
You can use the official Facebook SDK to handle the user authentication and redirect flow from a client application. Once authenticated, the Facebook SDK returns an access token that you can send to your app and use to finish logging the user in to your app.
auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); auto accessToken = "<token>"; auto user = app.login(realm::App::credentials::facebook(accessToken)).get();
var user = await app.LogInAsync(Credentials.Facebook(facebookToken));
final facebookCredentials = Credentials.facebook(accessToken); final currentUser = await app.logIn(facebookCredentials);
FacebookSdk.setApplicationId(YOUR_FACEBOOK_SDK_APP_ID); FacebookSdk.sdkInitialize(activity); CallbackManager callbackManager = CallbackManager.Factory.create(); LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() { public void onSuccess(LoginResult loginResult) { // Signed in successfully, forward credentials to MongoDB Realm. AccessToken accessToken = loginResult.getAccessToken(); Credentials facebookCredentials = Credentials.facebook(accessToken.getToken()); app.loginAsync(facebookCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully logged in to MongoDB Realm using Facebook OAuth."); } else { Log.e("AUTH", "Failed to log in to MongoDB Realm", it.getError()); } }); } public void onCancel() { Log.v("AUTH", "Facebook authentication cancelled."); } public void onError(FacebookException exception) { Log.e("AUTH", "Failed to authenticate using Facebook: " + exception.getMessage()); } } ); LoginManager.getInstance().logIn(activity, null);
// Get the access token from the Facebook SDK const { accessToken } = FB.getAuthResponse(); // Define credentials with the access token from the Facebook SDK const credentials = Realm.Credentials.facebook(accessToken); // Log the user in to your app await app.logIn(credentials);
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID FacebookSdk.setApplicationId(YOUR_FACEBOOK_SDK_APP_ID) FacebookSdk.sdkInitialize(activity) val callbackManager = CallbackManager.Factory.create() LoginManager.getInstance().registerCallback( callbackManager, object : FacebookCallback<LoginResult> { override fun onSuccess(loginResult: LoginResult) { // Signed in successfully, forward credentials to MongoDB Realm. val accessToken = loginResult.accessToken runBlocking { val user = app.login(Credentials.facebook(accessToken.token)) } } override fun onCancel() { Log.v("AUTH", "Cancelled Facebook login") } override fun onError(exception: FacebookException) { Log.e("AUTH", "Failed to authenticate with Facebook: ${exception.message}") } })
FacebookSdk.setApplicationId(YOUR_FACEBOOK_SDK_APP_ID) FacebookSdk.sdkInitialize(activity) val callbackManager = CallbackManager.Factory.create() LoginManager.getInstance().registerCallback( callbackManager, object : FacebookCallback<LoginResult> { override fun onSuccess(loginResult: LoginResult) { // Signed in successfully, forward credentials to MongoDB Realm. val accessToken = loginResult.accessToken val facebookCredentials: Credentials = Credentials.facebook(accessToken.token) app.loginAsync(facebookCredentials) { if (it.isSuccess) { Log.v( "AUTH", "Successfully logged in to MongoDB Realm using Facebook OAuth." ) } else { Log.e("AUTH", "Failed to log in to MongoDB Realm", it.error) } } } override fun onCancel() { Log.v("AUTH", "Cancelled Facebook login") } override fun onError(exception: FacebookException) { Log.e("AUTH", "Failed to authenticate with Facebook: ${exception.message}") } })
// This example demonstrates login logic for FBSDK version 13.x. If you're using // a different version of FBSDK, you'll need to adapt this example for your version. let loginManager = LoginManager() loginManager.logIn(permissions: [ .email ]) { loginResult in switch loginResult { case .success(let grantedPermissions, let declinedPermissions, let accessToken): let credentials = Credentials.facebook(accessToken: accessToken!.tokenString) app.login(credentials: credentials) { result in DispatchQueue.main.async { switch result { case .failure(let error): print("Failed to log in to MongoDB Realm: \(error)") case .success(let user): print("Successfully logged in to MongoDB Realm using Facebook OAuth.") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } } } case .failed(let error): print("Facebook login failed: \(error)") case .cancelled: print("The user cancelled the login flow.") } }
// The documentation does not currently have this code example in TypeScript. // Please refer to the other languages or related pages for example code.
Apple
The Sign-in with Apple authentication provider enables users to log in to your application with a custom token provided by Apple. Refer to Apple ID Authentication in the App Services documentation for more information.
To log in with Apple authentication, pass an Apple access token to
Credentials.apple().
Then pass the credential to app.logIn
.
To log in with Sign-in with Apple authentication, create a
Sign-in with Apple credential by calling Credentials.apple()
with the token provided by Apple. Then pass the generated credential
to app.login()
or app.loginAsync()
.
You can use the official Sign in with Apple JS SDK to handle the user authentication and redirect flow from a client application. Once authenticated, the Apple JS SDK returns an ID token that you can send to your app and use to finish logging the user in to your app.
To log in with Apple authentication, create an Apple credential by calling Credentials.apple() with the user's token, and then pass the generated credential to app.login():
Kotlin Multiplatform (KMP) supports many environments, but this example shows sign-in on the Android platform. For information about signing in with Apple on Apple platforms, switch the language selector on this page to Swift.
To log in with Sign-in with Apple authentication, create a
Sign-in with Apple credential by calling Credentials.apple()
with the token provided by Apple. Then pass the generated credential
to app.login()
or app.loginAsync()
.
You can use the official Sign in with Apple JS SDK to handle the user authentication and redirect flow from a client application. Once authenticated, the Apple JS SDK returns an ID token that you can send to your app and use to finish logging the user in to your app.
auto appConfig = realm::App::configuration(); appConfig.app_id = APP_ID; auto app = realm::App(appConfig); auto idToken = "<token>"; auto user = app.login(realm::App::credentials::apple(idToken)).get();
var user = await app.LogInAsync(Credentials.Apple(appleToken));
final appleCredentials = Credentials.apple(idToken); final currentUser = await app.logIn(appleCredentials);
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); // fetch apple token using Apple SDK Credentials appleCredentials = Credentials.apple("<token>"); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(appleCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated using Sign-in with Apple."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
// Get the ID token from the Apple SDK const { id_token } = await AppleID.auth.signIn(); // Define credentials with the ID token from the Apple SDK const credentials = Realm.Credentials.apple(id_token); // Log the user in to your app const user = await app.logIn(credentials);
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { // Registration is handled by Apple val appleCredentials = Credentials.apple(idToken) val user = app.login(appleCredentials) }
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) // fetch IDToken using Apple SDK val appleCredentials: Credentials = Credentials.apple("<token>") var user: User? = null app.loginAsync(appleCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated using Sign-in with Apple.") user = app.currentUser() } else { Log.e("AUTH", "Error logging in: ${it.error.toString()}") } }
// Fetch IDToken via the Apple SDK let credentials = Credentials.apple(idToken: "<token>") app.login(credentials: credentials) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
// The documentation does not currently have this code example in TypeScript. // Please refer to the other languages or related pages for example code.
Tip
If you get a Login failed
error saying that the token contains
an invalid number of segments
, verify that you're passing a UTF-8-encoded
string version of the JWT.
Log In Offline
When your application authenticates a user, it caches the user's credentials. You can check for existing user credentials to bypass the login flow and access the cached user. Use this to open a synced database offline.
Note
Initial login requires a network connection
When a user signs up for your app, or logs in for the first time with an existing account on a client, the device must have a network connection. Checking for cached user credentials lets you open a synced database offline, but only if the user has previously logged in on the device while online.
// The documentation does not currently have this code example in C++. // Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in C#. // Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Dart. // Please refer to the other languages or related pages for example code.
// Log the user into the backend app. // The first time you login, the user must have a network connection. String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); // Check for an existing user. // If the user is offline but credentials are // cached, this returns the existing user. AtomicReference<User> user = new AtomicReference<User>(); user.set(app.currentUser()); if (user.get() == null) { // If the device has no cached user // credentials, log them in. Credentials anonymousCredentials = Credentials.anonymous(); app.loginAsync(anonymousCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated anonymously."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } }); }
// The documentation does not currently have this code example in JavaScript. // Please refer to the other languages or related pages for example code.
// You can only open a synced realm offline if there is a cached user credential. If // there is no app.currentUser, you must log them in, which requires a network connection. if (app.currentUser == null) { app.login(Credentials.emailPassword(email, password)) } // If the app.currentUser isn't null, you can use the cached credential to open the synced // realm even if the user is offline. val user = app.currentUser!! val realm = Realm.open(config) // Query the realm we opened, and see that it contains data val offlineToads: RealmResults<Toad> = realm.query<Toad>().find() Log.v("After opening a realm offline, offlineToads.size is ${offlineToads.size}") realm.close()
// Log the user into the backend app. // The first time you login, the user must have a network connection. val appID = YOUR_APP_ID // replace this with your App ID val app = App( AppConfiguration.Builder(appID) .build() ) // Check for an existing user. // If the user is offline but credentials are // cached, this returns the existing user. val user = AtomicReference<User?>() user.set(app.currentUser()) if (user.get() == null) { // If the device has no cached user // credentials, log them in. val anonymousCredentials = Credentials.anonymous() app.loginAsync( anonymousCredentials ) { it: App.Result<User?> -> if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated anonymously.") user.set(app.currentUser()) } else { Log.e("AUTH", it.error.toString()) } } }
// Log the user into the backend app. // The first time you login, the user must have a network connection. func getUser() async throws -> User { // Check for an existing user. // If the user is offline but credentials are // cached, this returns the existing user. if let user = app.currentUser { return user } else { // If the device has no cached user // credentials, log them in. let app = App(id: YOUR_APP_SERVICES_APP_ID) let loggedInUser = try await app.login(credentials: Credentials.anonymous) return loggedInUser } } let user = try await getUser() var configuration = user.configuration(partitionValue: "Some Partition Value") // Open a Realm with this configuration. // If you do not require the app to download updates // before opening the realm, the realm just opens, even if // offline. let realm = try await Realm(configuration: configuration) print("Successfully opened realm: \(realm)")
// The documentation does not currently have this code example in TypeScript. // Please refer to the other languages or related pages for example code.
Log a User Out
Warning
When a user logs out, you can no longer read or write data in any synced databases that the user opened. As a result, any operation that has not yet completed before the initiating user logs out cannot complete successfully and will likely result in an error. Any data in a write operation that fails in this way will be lost.
The log out method:
Deletes locally stored user credentials from the device.
Immediately halts any synchronization to and from the user's synced databases.
For anonymous users, removes the user.
Because logging out halts synchronization, you should only log out after all synced database updates have uploaded to the server.
Once logged in, you can log out by calling the LogOutAsync()
method:
You can log out any user, regardless of the authentication provider used to log in, using User.logOut().
You can log out any user, regardless of the authentication provider used
to log in, using the user.logOut()
or user.logOutAsync()
methods.
To log any user out, call the User.logOut()
on their user instance.
You can log out any user, regardless of the authentication provider used to log in, using user.logOut():
You can log out any user, regardless of the authentication provider used
to log in, using the user.logOut()
or user.logOutAsync()
methods.
To log any user out, call the User.logOut()
on their user instance.
user.log_out().get();
await user.LogOutAsync();
await user.logOut();
user.get().logOutAsync( result -> { if (result.isSuccess()) { Log.v("AUTH", "Successfully logged out."); } else { Log.e("AUTH", result.getError().toString()); } });
// Log out the current user await app.currentUser?.logOut();
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { val user = app.login(credentials) // ... work with logged-in user ... // Ensure all local updates are uploaded // before logging out user.logOut() }
user?.logOutAsync { if (it.isSuccess) { Log.v("AUTH", "Successfully logged out.") } else { Log.e("AUTH", it.error.toString()) } }
app.currentUser?.logOut { (error) in // user is logged out or there was an error }
// The documentation does not currently have this code example in TypeScript. // Please refer to the other languages or related pages for example code.
Observe Authentication Changes
Some SDKs provide platform-idiomatic APIs to observe authentication changes. In other SDKs, you can use platform or language-specific architecture to achieve a similar result without a dedicated API.
C++ does not provide a dedicated API to observe authentication changes. However, you can check the user's state, which is an enum whose possible values are:
logged_out
logged_in
removed
New in version v11.6.0.
You can observe a flow of authentication change events by calling User.Changed() on a valid user object.
Currently, User.Changed()
triggers on all user events and you should add a
handler to ensure your responses to events are idempotent.
New in version 10.8.0.
You can observe a flow of authentication change events by calling App.authenticationChangeAsFlow(). This flow emits AuthenticationChange events of three possible states, represented as subclasses:
LoggedIn
: A user logs into the app.LoggedOut
: A a user logs out of the app.Removed
: A user is removed from the app, which also logs them out.
These events contain a user
property that provides a reference to the
User
object that has logged in, logged out, or been removed.
// The C++ SDK does not currently support this API.
app.CurrentUser.Changed += (change, _) => { Debug.WriteLine($"Auth change: {change}, {_}"); };
// The Flutter SDK does not currently support this API.
// The Java SDK does not support this API.
// The Node.js SDK does not currently support this API.
// Create a Flow of AuthenticationChange objects app.authenticationChangeAsFlow().collect { change: AuthenticationChange -> when (change) { is LoggedIn -> proceedToAppActivity(change.user) is LoggedOut -> proceedToLoginActivity(change.user) is Removed -> proceedToRemovedUserActivity(change.user) } }
// The Java SDK does not support this API.
// The Swift SDK does not currently support this API.
// This API is not currently available in TypeScript.
Get the Current User
When a user logs in through an App
on a device, we cache that App and user
information on the device. You can retrieve the currently logged-in user to
perform app operations without having to log the user in again.
You can continue to work with the current user until the user session expires. When the session expires, the SDK automatically uses a refresh token to start a new session. When the refresh token expires, the SDK cannot start a new session and the user must log in again. You can configure refresh token expiration time in Atlas. For more information, refer to Configure Refresh Token Expiration in the App Services documentation.
If you have multiple users logged in to your app, retrieving a current user returns the last valid user that logged in. It returns null or nil, depending on the language, if there are no logged-in users. Refer to Multi-User Applications for more information.
You can get the current user with app::get_current_user()
:
Once you have an authenticated user, you can retrieve the User object with the App.CurrentUser property.
Once you have an authenticated user, you can retrieve the User object with the App.currentUser property.
To retrieve the currently logged-in user with the App.currentUser property:
auto currentUser = app.get_current_user();
// The documentation does not currently have this code example in C#. // Please refer to the other languages or related pages for example code.
final user = app.currentUser;
// The documentation does not have this code example in Java. // Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in JavaScript. // Please refer to the other languages or related pages for example code.
val user = app.currentUser
// The documentation does not have this code example in Kotlin for the Java SDK. // Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Swift. // Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in TypeScript. // Please refer to the other languages or related pages for example code.