Navigation

Authenticate a User

Overview

The React Native SDK provides developers with a unified API to authenticate application users for any authentication provider. Users log in by providing authentication credentials for a given authentication provider and the SDK automatically manages authentication tokens and refreshes data for logged in users.

Log In

Anonymous

The Anonymous provider allows users to log in to your application with ephemeral accounts that have no associated information.

To log in, create an anonymous credential and pass it to App.logIn():

async function loginAnonymous() {
  // Create an anonymous credential
  const credentials = Realm.Credentials.anonymous();
  try {
    // Authenticate the user
    const user: Realm.User = await app.logIn(credentials);
    // `App.currentUser` updates to match the logged in user
    assert(user.id === app.currentUser.id)
    return user
  } catch(err) {
    console.error("Failed to log in", err);
  }
}
loginAnonymous().then(user => {
  console.log("Successfully logged in!", user)
})
async function loginAnonymous() {
  // Create an anonymous credential
  const credentials = Realm.Credentials.anonymous();
  try {
    // Authenticate the user
    const user = await app.logIn(credentials);
    // `App.currentUser` updates to match the logged in user
    assert(user.id === app.currentUser.id)
    return user
  } catch(err) {
    console.error("Failed to log in", err);
  }
}
loginAnonymous().then(user => {
  console.log("Successfully logged in!", user)
})

Email/Password

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

async function loginEmailPassword(email: string, password: string) {
  // Create an anonymous credential
  const credentials = Realm.Credentials.emailPassword(email, password);
  try {
    // Authenticate the user
    const user: Realm.User = await app.logIn(credentials);
    // `App.currentUser ` updates to match the logged in user
    assert(user.id === app.currentUser.id)
    return user
  } catch(err) {
    console.error("Failed to log in", err);
  }
}
loginEmailPassword("cal.kestis@example.com", "Bogano123!").then(user => {
  console.log("Successfully logged in!", user)
})
async function loginEmailPassword(email, password) {
  // Create an anonymous credential
  const credentials = Realm.Credentials.emailPassword(email, password);
  try {
    // Authenticate the user
    const user = await app.logIn(credentials);
    // `App.currentUser` updates to match the logged in user
    assert(user.id === app.currentUser.id)
    return user
  } catch(err) {
    console.error("Failed to log in", err);
  }
}
loginEmailPassword("cal.kestis@example.com", "Bogano123!").then(user => {
  console.log("Successfully logged in!", user)
})

API Key

The API key authentication provider allows server processes to access 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():

async function loginApiKey(apiKey: string) {
  // Create an API Key credential
  const credentials = Realm.Credentials.apiKey(apiKey);
  try {
    // Authenticate the user
    const user: Realm.User = await app.logIn(credentials);
    // `App.currentUser` updates to match the logged in user
    assert(user.id === app.currentUser.id)
    return user
  } catch(err) {
    console.error("Failed to log in", err);
  }
}
loginApiKey("To0SQOPC...ZOU0xUYvWw").then(user => {
  console.log("Successfully logged in!", user)
})
async function loginApiKey(apiKey) {
  // Create an API Key credential
  const credentials = Realm.Credentials.apiKey(apiKey);
  try {
    // Authenticate the user
    const user = await app.logIn(credentials);
    // `App.currentUser` updates to match the logged in user
    assert(user.id === app.currentUser.id)
    return user
  } catch(err) {
    console.error("Failed to log in", err);
  }
}
loginApiKey("To0SQOPC...ZOU0xUYvWw").then(user => {
  console.log("Successfully logged in!", user)
})

Custom Function

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

async function loginCustomFunction(payload: Realm.Credentials.FunctionPayload) {
  // Create a Custom Function credential
  const credentials = Realm.Credentials.function(payload);
  try {
    // Authenticate the user
    const user: Realm.User = await app.logIn(credentials);
    // `App.currentUser` updates to match the logged in user
    assert(user.id === app.currentUser.id);
    return user;
  } catch (err) {
    console.error("Failed to log in", err);
  }
}
loginCustomFunction({ username: "mongolover" }).then((user) => {
  console.log("Successfully logged in!", user);
});
async function loginCustomFunction(payload) {
  // Create a Custom Function credential
  const credentials = Realm.Credentials.function(payload);
  try {
    // Authenticate the user
    const user = await app.logIn(credentials);
    // `App.currentUser` updates to match the logged in user
    assert(user.id === app.currentUser.id);
    return user;
  } catch (err) {
    console.error("Failed to log in", err);
  }
}
loginCustomFunction({ username: "mongolover" }).then((user) => {
  console.log("Successfully logged in!", user);
});

Custom JWT

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

async function loginCustomJwt(jwt: Realm.Credentials.JWTPayload) {
  // Create a Custom JWT credential
  const credentials = Realm.Credentials.jwt(jwt);
  try {
    // Authenticate the user
    const user: Realm.User = await app.logIn(credentials);
    // `App.currentUser` updates to match the logged in user
    assert(user.id === app.currentUser.id);
    return user;
  } catch (err) {
    console.error("Failed to log in", err);
  }
}
loginCustomJwt("eyJ0eXAi...Q3NJmnU8oP3YkZ8").then((user) => {
  console.log("Successfully logged in!", user);
});
async function loginCustomJwt(jwt) {
  // Create a Custom JWT credential
  const credentials = Realm.Credentials.jwt(jwt);
  try {
    // Authenticate the user
    const user = await app.logIn(credentials);
    // `App.currentUser` updates to match the logged in user
    assert(user.id === app.currentUser.id);
    return user;
  } catch (err) {
    console.error("Failed to log in", err);
  }
}
loginCustomJwt("eyJ0eXAi...Q3NJmnU8oP3YkZ8").then((user) => {
  console.log("Successfully logged in!", user);
});

Facebook OAuth

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

Enable the Facebook Auth Provider

To authenticate a Facebook user, you must configure the Facebook authentication provider.

You can use the official Facebook React Native 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 use to finish logging the user in to your app.

import React from "react";
import { View } from "react-native";
import Realm from "realm";
import { LoginButton, AccessToken } from "react-native-fbsdk";

const Login: React.FC<{ app: Realm.App }> = ({ app }) => {
  return (
    <View>
      <LoginButton
        onLoginFinished={async (error, result) => {
          if (error) {
            console.error(`Failed to log in: ${result.error}`);
          } else if (result.isCancelled) {
            console.log("Facebook login was cancelled");
          } else {
            const { accessToken } = await AccessToken.getCurrentAccessToken();
            const credential = Realm.Credentials.facebook(accessToken);
            const user: Realm.User = await app.logIn(credential);
            console.log(`Logged in with id: ${user.id}`);
          }
        }}
      />
    </View>
  );
};
export default Login;
import React from "react";
import { View } from "react-native";
import Realm from "realm";
import { LoginButton, AccessToken } from "react-native-fbsdk";

const Login = ({ app }) => {
  return (
    <View>
      <LoginButton
        onLoginFinished={async (error, result) => {
          if (error) {
            console.error(`Failed to log in: ${result.error}`);
          } else if (result.isCancelled) {
            console.log("Facebook login was cancelled");
          } else {
            const { accessToken } = await AccessToken.getCurrentAccessToken();
            const credential = Realm.Credentials.facebook(accessToken);
            const user = await app.logIn(credential);
            console.log(`Logged in with id: ${user.id}`);
          }
        }}
      />
    </View>
  );
};
export default Login;

Google OAuth

The Google authentication provider allows you to authenticate users through a Google project using their existing Google account.

Enable the Google Auth Provider

To authenticate a Google user, you must configure the Google authentication provider.

You can use a community-maintained package, such as React Native Google Sign In, to render a sign-in button and handle the user authentication flow. Once authenticated, get the user’s server authorization code to finish logging the user in to your app.

import React from "react";
import { View } from "react-native";
import Realm from "realm";
import { GoogleSignin, GoogleSigninButton, statusCodes } from '@react-native-community/google-signin';

// You must configure `webClientId` and `offlineAccess` to get the auth code
GoogleSignin.configure({
  webClientId: '<Google Project Client ID>',
  offlineAccess: true,
});

// Handle the Google Sign In flow and return the auth code
async function getGoogleAuthCode(): Promise<string> {
  try {
    await GoogleSignin.hasPlayServices();
    const { serverAuthCode } = await GoogleSignin.signIn()
    return serverAuthCode
  } catch (error) {
    switch(error.code) {
      case statusCodes.SIGN_IN_CANCELLED: {
        // user cancelled the login flow
      }
      case statusCodes.IN_PROGRESS: {
        // operation (e.g. sign in) is in progress already
      }
      case statusCodes.PLAY_SERVICES_NOT_AVAILABLE: {
        // play services not available or outdated
      }
      default: {
        // some other error happened
      }
    }
  }
}

const Login: React.FC<{ app: Realm.App }> = ({ app }) => {
  return (
    <View>
      <GoogleSigninButton
        size={GoogleSigninButton.Size.Standard}
        color={GoogleSigninButton.Color.Auto}
        onPress={async () => {
          const serverAuthCode: string = await getGoogleAuthCode();
          const credential = Realm.Credentials.google(serverAuthCode);
          const user: Realm.User = await app.logIn(credential);
          console.log(`Logged in with id: ${user.id}`);
        }}
      />
    </View>
  );
};
export default Login;
import React from "react";
import { View } from "react-native";
import Realm from "realm";
import { GoogleSignin, GoogleSigninButton, statusCodes } from '@react-native-community/google-signin';

// You must configure `webClientId` and `offlineAccess` to get the auth code
GoogleSignin.configure({
  webClientId: '<Google Project Client ID>',
  offlineAccess: true,
});

// Handle the Google Sign In flow and return the auth code
async function getGoogleAuthCode() {
  try {
    await GoogleSignin.hasPlayServices();
    const { serverAuthCode } = await GoogleSignin.signIn()
    return serverAuthCode
  } catch (error) {
    switch(error.code) {
      case statusCodes.SIGN_IN_CANCELLED: {
        // user cancelled the login flow
      }
      case statusCodes.IN_PROGRESS: {
        // operation (e.g. sign in) is in progress already
      }
      case statusCodes.PLAY_SERVICES_NOT_AVAILABLE: {
        // play services not available or outdated
      }
      default: {
        // some other error happened
      }
    }
  }
}

const Login = ({ app }) => {
  return (
    <View>
      <GoogleSigninButton
        size={GoogleSigninButton.Size.Standard}
        color={GoogleSigninButton.Color.Auto}
        onPress={async () => {
          const serverAuthCode = await getGoogleAuthCode();
          const credential = Realm.Credentials.google(serverAuthCode);
          const user = await app.logIn(credential);
          console.log(`Logged in with id: ${user.id}`);
        }}
      />
    </View>
  );
};
export default Login;

Sign-in with Apple

The Apple authentication provider allows you to authenticate users through Sign-in With Apple.

Enable the Apple Auth Provider

To authenticate an Apple user, you must configure the Apple authentication provider.

You can use a community-maintained package, such as React Native Apple Authentication, to render a sign-in button and handle the user authentication flow. Once authenticated, get the user’s ID token to finish logging the user in to your app.

import React from "react";
import { View } from "react-native";
import Realm from "realm";
import appleAuth, {
  AppleButton,
  AppleAuthRequestOperation,
  AppleAuthRequestScope,
  AppleAuthCredentialState,
} from '@invertase/react-native-apple-authentication';

async function getAppleIdentityToken(): Promise<string> {
  // performs login request
  const appleAuthRequestResponse = await appleAuth.performRequest({
    requestedOperation: AppleAuthRequestOperation.LOGIN,
    requestedScopes: [AppleAuthRequestScope.EMAIL, AppleAuthRequestScope.FULL_NAME],
  });

  // get current authentication state for user
  // /!\ This method must be tested on a real device. On the iOS simulator it always throws an error.
  const credentialState = await appleAuth.getCredentialStateForUser(appleAuthRequestResponse.user);

  // use credentialState response to ensure the user is authenticated
  if (credentialState === AppleAuthCredentialState.AUTHORIZED) {
    return appleAuthRequestResponse.identityToken;
  } else {
    throw new Error("Failed to get Apple ID token.")
  }
}

const Login = ({ app }) => {
  return (
    <View>
      <AppleButton
        buttonStyle={AppleButton.Style.WHITE}
        buttonType={AppleButton.Type.SIGN_IN}
        onPress={async () => {
          const identityToken = await getAppleIdentityToken();
          const credential = Realm.Credentials.apple(identityToken);
          const user: Realm.User = await app.logIn(credential);
          console.log(`Logged in with id: ${user.id}`);
        }}
      />
    </View>
  );
};
export default Login;
import React from "react";
import { View } from "react-native";
import Realm from "realm";
import appleAuth, {
  AppleButton,
  AppleAuthRequestOperation,
  AppleAuthRequestScope,
  AppleAuthCredentialState,
} from '@invertase/react-native-apple-authentication';

async function getAppleIdentityToken() {
  // performs login request
  const appleAuthRequestResponse = await appleAuth.performRequest({
    requestedOperation: AppleAuthRequestOperation.LOGIN,
    requestedScopes: [AppleAuthRequestScope.EMAIL, AppleAuthRequestScope.FULL_NAME],
  });

  // get current authentication state for user
  // /!\ This method must be tested on a real device. On the iOS simulator it always throws an error.
  const credentialState = await appleAuth.getCredentialStateForUser(appleAuthRequestResponse.user);

  // use credentialState response to ensure the user is authenticated
  if (credentialState === AppleAuthCredentialState.AUTHORIZED) {
    return appleAuthRequestResponse.identityToken;
  } else {
    throw new Error("Failed to get Apple ID token.")
  }
}

const Login = ({ app }) => {
  return (
    <View>
      <AppleButton
        buttonStyle={AppleButton.Style.WHITE}
        buttonType={AppleButton.Type.SIGN_IN}
        onPress={async () => {
          const identityToken = await getAppleIdentityToken();
          const credential = Realm.Credentials.apple(identityToken);
          const user = await app.logIn(credential);
          console.log(`Logged in with id: ${user.id}`);
        }}
      />
    </View>
  );
};
export default Login;

Log Out

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

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();
// Log out a specific user
await app.allUsers[2].logOut();
// Log out the current user
await app.currentUser.logOut();
// Log out a specific user
await app.allUsers[2].logOut();