Authenticate Users - React Native SDK
On this page
The SDK provides an API for authenticating users using any enabled
authentication provider. Instantiate a Realm.Credentials
object and pass it to Realm.App.logIn()
to authenticate and obtain a Realm.User object.
The Realm.Credentials
class exposes factory methods that correspond to
each of the authentication providers.
Prerequisites
Before you can authenticate a user, you must:
Enable one or more authentication providers in the App.
Configure User Authentication in Client
Configure user authentication with the @realm/react
AppProvider
and UserProvider
components and useApp()
and useUser()
hooks.
To set up user authentication:
Wrap all components you want to use with App Services in an
AppProvider
component.Inside of
AppProvider
, wrap all components that you want to have access to an authenticated user with aUserProvider
component.In
UserProvider
, include afallback
prop with another component that logs a user in. The app renders this component if there is no authenticated user.In the component passed to the
UserProvider.fallback
prop, authenticate a user withRealm.App.logIn()
, which you can access with theuseApp()
hook.
Components wrapped by UserProvider
only render if your app has
an authenticated user. These components can access the authenticated user
with the useUser()
hook.
import React from 'react'; import {useApp, UserProvider, AppProvider} from '@realm/react'; import {Button} from 'react-native'; function AppWrapper() { return ( <AppProvider id={APP_ID}> {/* If there is no authenticated user, the app mounts the `fallback` component. Once the user successfully authenticates, the app unmounts the component in the `UserProvider.fallback` prop (the `LogIn` component in this example). */} <UserProvider fallback={LogIn}> {/* Components with access to the user. These components only mount if there's an authenticated user.*/} <RestOfApp /> </UserProvider> </AppProvider> ); } function LogIn() { const app = useApp(); // This example uses anonymous authentication. // However, you can use any authentication provider // to log a user in with this pattern. async function logInUser() { await app.logIn(Realm.Credentials.anonymous()); } return ( <Button title='Log In' onPress={logInUser} /> ); }
Log In
Realm provides an API for authenticating users using any enabled
authentication provider. Instantiate a Credentials
object and pass it to the
app.login()
method to authenticate a user login and create a User
object.
User Sessions
The React Native SDK communicates with Atlas App Services to manage sessions with access tokens and refresh tokens.
To learn more about session management, refer to User Sessions in the App Services documentation.
Anonymous User
The Anonymous provider allows users to log in to your application with temporary accounts that have no associated information.
To log in, create an anonymous credential and pass it to App.logIn()
:
// Create an anonymous credential const credentials = Realm.Credentials.anonymous(); const user = await app.logIn(credentials);
Email/Password User
The email/password authentication provider allows users to log in to your application with an email address and a password.
To log in, create an email/password credential with the user's email address and
password and pass it to App.logIn()
:
// Create an email/password credential const credentials = Realm.Credentials.emailPassword( "someone@example.com", "Pa55w0rd!" ); const user = await app.logIn(credentials);
API Key User
The API key authentication provider allows server processes to access your app directly or on behalf of a user.
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()
:
// 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 JWT User
The Custom JWT authentication provider allows you to handle user authentication with any authentication system that returns a JSON web token.
To log in, create a Custom JWT credential with a JWT from the external system
and pass it to App.logIn()
:
// Create a custom jwt credential const jwt = await authenticateWithExternalSystem(); const credentials = Realm.Credentials.jwt(jwt); const user = await app.logIn(credentials);
Custom Function User
The Custom Function authentication provider allows you to handle user authentication by running a function that receives a payload of arbitrary information about a user.
To log in with the custom function provider, create a Custom Function credential
with a payload object and pass it to App.logIn()
:
// Create a custom function credential const credentials = Realm.Credentials.function({ username: "ilovemongodb", }); const user = await app.logIn(credentials);
Facebook User
The Facebook authentication provider allows you to authenticate users through a Facebook app using their existing Facebook account.
To log a user in with their existing Facebook account, you must configure and enable the Facebook authentication provider for your App Services App.
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.
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 React Native app and use to finish logging the user in to your app.
// Get the access token from a client application using the Facebook SDK const accessToken = getFacebookAccessToken(); // Log the user in to your app const credentials = Realm.Credentials.facebook(accessToken); app.logIn(credentials).then(user => { console.log(`Logged in with id: ${user.id}`); });
Google User
The Google authentication provider allows you to authenticate users with their existing Google account.
To authenticate a Google user, you must configure the Google authentication provider for your App Services App.
There is no official Sign in with Google integration with React Native. The simplest approach to integrating Sign in With Google into your React Native app with Realm authentication is to use a third-party library. The below example uses the library React Native Google Sign In. You can also build your own solution using Google Identity Services to handle the user authentication and redirect flow from a client application.
Regardless of implementation, you must retrieve an ID token from the Google Authorization server. Use that ID token to log into Realm.
// Get the Google OAuth 2.0 access token const idToken = getGoogleAccessToken(); // Log the user in to your app const credentials = Realm.Credentials.google({ idToken }); app.logIn(credentials).then((user) => { console.log(`Logged in with id: ${user.id}`); });
Example
Authenticate with Google in React Native
This example uses the library
React Native Google Sign In.
In addition to the React Native code, you must also set up additional configuration
in your project's ios
and android
directories to use Sign in with Google.
Refer to the package's documentation for
iOS-specific
and Android-specific
documentation.
import { useState } from "react"; import { GoogleSignin, GoogleSigninButton, statusCodes, } from "@react-native-google-signin/google-signin"; import Realm from "realm"; // Instantiate Realm app const app = new Realm.App({ id: "<Your App ID>", }); // Configure Google Auth GoogleSignin.configure({ webClientId: "<Your Web Client ID>", }); export default function GoogleSignInButton() { const [signinInProgress, setSigninInProgress] = useState(false); const signIn = async () => { setSigninInProgress(true); try { // Sign into Google await GoogleSignin.hasPlayServices(); const { idToken } = await GoogleSignin.signIn(); // use Google ID token to sign into Realm const credential = Realm.Credentials.google({ idToken }); const user = await app.logIn(credential); console.log("signed in as Realm user", user.id); } catch (error) { // handle errors if (error.code === statusCodes.SIGN_IN_CANCELLED) { // user cancelled the login flow } else if (error.code === statusCodes.IN_PROGRESS) { // operation (e.g. sign in) is in progress already } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) { // play services not available or outdated } else { // some other error happened } } finally { setSigninInProgress(false); } }; // return Google Sign in button component return ( <GoogleSigninButton style={{ width: 192, height: 48 }} size={GoogleSigninButton.Size.Wide} color={GoogleSigninButton.Color.Dark} onPress={signIn} disabled={signinInProgress} /> ); }
Apple User
The Apple authentication provider allows you to authenticate users through Sign-in With Apple.
To authenticate an Apple user, you must configure the Apple authentication provider for your App Services App.
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 React Native app and use to finish logging the user in to your app.
// Get the access token from a client application using the Apple JS SDK const idToken = getAppleIdToken(); // Log the user in to your app const credentials = Realm.Credentials.apple(idToken); app.logIn(credentials).then(user => { console.log(`Logged in with id: ${user.id}`); });
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.
Offline Login
When your Realm 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 realm 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 client must have a network connection. Checking for cached user credentials lets you open a realm offline, but only if the user has previously logged in while online.
// Log user into your App Services App. // On first login, the user must have a network connection. const getUser = async () => { // If the device has no cached user credentials, log in. if (!app.currentUser) { const credentials = Realm.Credentials.anonymous(); await app.logIn(credentials); } // If the app is offline, but credentials are // cached, return existing user. return app.currentUser!; };
To learn how to use the cached user in the Sync Configuration and access a realm while offline, read the Open a Synced Realm While Offline docs.
Get a User Access Token
When a user logs in, Atlas App Services creates an access token for the user that grants them access to your App. The Realm SDK automatically manages access tokens, refreshes them when they expire, and includes a valid access token for the current user with each request. Realm does not automatically refresh the refresh token. When the refresh token expires, the user must log in again.
If you send requests outside of the SDK (for example, through the GraphQL API) then you need to include the user's access token with each request, and manually refresh the token when it expires.
You can access and refresh a logged in user's access token in the SDK from their
Realm.User
object, as in the following example:
Refresh Token Expiration
Refresh tokens expire after a set period of time. When the refresh token expires, the access token can no longer be refreshed and the user must log in again.
If the refresh token expires after the realm is open, the device will not be able to sync until the user logs in again. Your sync error handler should implement logic that catches a token expired error when attempting to sync, then redirect users to a login flow.
For information on configuring refresh token expiration, refer to Manage User Sessions in the App Services documentation.
Log a User Out
To log any user out, call the User.logOut()
on their user instance.
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.
// Log out the current user await app.currentUser?.logOut();