Docs Menu

Docs HomeRealm

Authenticate Users - Kotlin SDK

On this page

  • Overview
  • Before You Begin
  • Register a New User Account
  • Log In
  • Anonymous
  • Email/Password
  • Custom JWT
  • API Key
  • Custom Function
  • Google
  • Facebook
  • Apple
  • Get a User Access Token
  • Log a User Out
  • Retrieve Current User
  • Authentication Changes as a Flow

Atlas App Services provides an API for authenticating users using any enabled authentication provider. Instantiate a Credentials object and pass it to app.login() to authenticate and create a User object for that user.

Each authentication provider corresponds to a static helper method used to instantiate Credentials objects for that authentication provider.

  1. Create an App Services App.

  2. Enable and configure one or more App Services authentication providers.

Realm registers accounts differently depending on the authentication provider:

  • You do not need to register anonymous users.

  • To register an email/password user, refer to Manage Email/Password Users.

  • If you are using Google, Facebook, Apple, or Custom JWT authentication, registration is handled by these third-party services.

You can authenticate users with app.login().

If successful, app.login() returns a User object. In the event of a failure, app.login() throws an exception of type AppException.

You can get the authentication provider type used to log in a user using the user.provider property. If the user is currently logged out, the provider last used to log in the user will be returned.

The anonymous authentication provider enables users to log in to your application with short-term accounts that store no persistent personal information. 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 { // use runBlocking sparingly -- it can delay UI interactions
val user = app.login(Credentials.anonymous())
}

If you want more than one anonymous user, set reuseExisting = false when creating additional anonymous credentials.

runBlocking {
// Logs in with anonymous user
val anonUser = app.login(Credentials.anonymous())
// Creates a new anonymous user
val otherAnonUser =
app.login(Credentials.anonymous(reuseExisting = false))
}

The Email/Password authentication provider enables users to log in to your application with an email username and a password. 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().

val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID
runBlocking { // use runBlocking sparingly -- it can delay UI interactions
val user = app.login(Credentials.emailPassword(email, password))
}

The Custom JWT authentication provider enables users to log in to your application with a custom JSON Web Token. To log in with JWT authentication, create a JWT credential by calling Credentials.jwt() with the user's JWT. Then pass the generated credential to app.login().

val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID
runBlocking { // use runBlocking sparingly -- it can delay UI interactions
val user = app.login(Credentials.jwt(jwtToken))
}

The API Key authentication provider enables users to log in to your application with an API key generated automatically in the client SDK. To log in with API key authentication, create an email/password credential by calling Credentials.apiKey() with the user's email and password. Then pass the generated credential to app.login().

val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID
runBlocking { // use runBlocking sparingly -- it can delay UI interactions
val user = app.login(Credentials.apiKey(key))
}

If you have configured the Custom Function authentication provider, you can log in using custom authentication logic handled by an Atlas Function.

To log in with Custom Function authentication, pass your custom arguments as a payload to Credentials.customFunction(). Then pass the generated credential to app.login().

val customCredentials = Credentials.customFunction(
payload = mapOf("username" to "bob")
)
// Pass the generated credential to app.login()
val currentUser = app.login(customCredentials)

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 EJSON Encoding for Atlas.

To set up your application for Google User authentication:

  1. In the Google Cloud Platform console, create an OAuth 2.0 client ID of type "Web application".

  2. Configure your backend App to use that client ID and the associated client secret.

  3. Enable OpenID Connect on the backend.

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():

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);
}
}

Tip

See also:

The Facebook authentication provider allows you to authenticate users through a Facebook app using their existing Facebook account.

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.

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 by calling Credentials.facebook() with the user's access token. Then pass the generated credential to app.login().

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}")
}
})

Tip

See also:

KMM supports many environments, but this example shows sign-in on the Android platform. For information about signing into a Facebook account on Apple platforms, see the Swift SDK Example.

The Sign-in with Apple authentication provider enables users to log in to your application with a custom token provided by Apple. To log in with Apple authentication, create an Apple credential by calling Credentials.apple() with the user's token. Then pass the generated credential to app.login().

val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID
runBlocking { // use runBlocking sparingly -- it can delay UI interactions
val user = app.login(Credentials.apple(idToken))
}

Tip

See also:

KMM supports many environments, but this example shows sign-in on the Android platform. For information about signing in with Apple on Apple platforms, see the Swift SDK Example.

The Realm Kotlin SDK automatically manages access tokens, refreshes them when they expire, and includes a valid access token for the current user with each request. Tokens are removed after the user logs out.

You can get the current access token for a logged-in user with the user.accessToken property:

val token = user.accessToken

If you send requests outside of the SDK (e.g. through the GraphQL API), then you must include the user's access token with each request and manually refresh the token when it expires. Access tokens expire 30 minutes after a user logs in.

You can get the current refresh token for a logged-in user with the user.refreshToken property, which you can use to request a new access token:

// Gets the current refresh token for the user
fun getRefreshToken(): String {
return user.refreshToken
}

Warning

When a user logs out, you can no longer read or write data in any synced realms 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.

You can log out any user, regardless of the authentication provider used to log in, using user.logOut().

The user.logOut() method:

  • Deletes locally stored user credentials from the device.

  • Immediately halts any synchronization to and from the user's realms.

Because logging out halts synchronization, you should only log out after all local Realm updates have uploaded to the server.

user.logOut()

Once you have an authenticated user, you can retrieve the User object with the App.currentUser property. The currentUser object is persisted in local storage, so even if the app shuts down after the initial authentication, you do not need to call logIn again (unless the user logged out).

val user = app.currentUser

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.

// 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)
}
}
←  Manage Users - Kotlin SDKManage Email/Password Users - Kotlin SDK →
Share Feedback
© 2023 MongoDB, Inc.

About

  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2023 MongoDB, Inc.