Orchestration SDKs

Device self-service in React Native apps

PingOne Advanced Identity Cloud PingAM React Native

The Device Client module for React Native provides a comprehensive and unified API for managing Multi-Factor Authentication (MFA) devices and user profile devices registered with Advanced Identity Cloud or PingAM servers.

The module simplifies the process of retrieving, updating, and deleting various types of authentication devices, enabling you to build secure and user-friendly device management experiences within your React Native applications.

Installing modules

To install the module into your React Native project, use yarn or npm as follows:

  • yarn

  • npm

yarn add @ping-identity/rn-device-client
npm install @ping-identity/rn-device-client

After installation, import the module as follows:

import { createDeviceClient } from '@ping-identity/rn-device-client';

Initializing the device client

The Device Client module uses the REST-based device management endpoints provided by Advanced Identity Cloud and PingAM.

The module requires a session token when making calls to the device management endpoints. In a React Native app, you must obtain the SSO token explicitly and pass it to the device client.

Session tokens often have a short duration and may expire after 5 minutes. If the client does not have an active session token, trigger an authentication journey to obtain a new one before attempting to manage registered devices.

Call createDeviceClient() after authenticating a user and obtaining their session token:

Initializing a device client on React Native
import { useJourney } from '@ping-identity/rn-journey';
import { createDeviceClient } from '@ping-identity/rn-device-client';
import type { JourneyClient } from '@ping-identity/rn-journey';

const [, journeyActions] = useJourney(journeyClient);

async function loadDevices() {
  const token = await journeyActions.ssoToken();
  if (!token) {
    // No active session — redirect to login
    return;
  }

  const deviceClient = createDeviceClient({
    serverUrl: 'https://openam-forgerock-sdks.forgeblocks.com/am',
    ssoToken: token.value,
    realm: 'alpha',
    cookieName: 'ch15fefc5407912',
  });

  try {
    const devices = await deviceClient.oath.get();
    // use devices
  } catch (error) {
    // Token may have expired. Re-authenticate and retry
    console.error('Failed to fetch devices:', error);
  } finally {
    await deviceClient.dispose();
  }
}

The configuration properties for the device client are as follows:

Device client parameters on React Native
Parameter Description Required?

serverUrl (String)

The base URL of your server, including the access management path.

PingOne Advanced Identity Cloud example

https://openam-forgerock-sdks.forgeblocks.com/am

PingAM example

https://openam.example.com:8443/openam

Yes

ssoToken (String)

The SSO token for the authenticated user.

Obtain this by calling journeyActions.ssoToken() after a successful Journey.

Yes

realm (String)

The authentication realm.

PingOne Advanced Identity Cloud example

alpha

PingAM example

root

Yes

cookieName (String)

The name of the SSO cookie configured on the server.

For example, PingAM servers use iPlanetDirectoryPro

How do I find my PingOne Advanced Identity Cloud cookie name?

To locate the cookie name in an PingOne Advanced Identity Cloud tenant:

  1. Navigate to Tenant settings > Global Settings

  2. Copy the value of the Cookie property.

Yes

logger (LoggerInstance)

Optional logger instance created by @ping-identity/rn-logger.

No

Listing registered devices

For each type of registered device, call the get() method to retrieve the list from the server.

The available device types are as follows:

Registered device type Listing method

WebAuthn / FIDO2 authenticators

deviceClient.webAuthn.get()

Bound devices

deviceClient.bound.get()

Device profiles

deviceClient.profile.get()

Push MFA devices

deviceClient.push.get()

OATH MFA devices (TOTP / HOTP)

deviceClient.oath.get()

Each method returns a Promise. Different device types return different information you can display to the user, such as the device name or last access date.

The following code shows how to obtain lists of the different devices from the server:

  • WebAuthn / FIDO

  • Bound devices

  • Profiled devices

  • Push devices

  • OATH devices

Listing WebAuthn devices on React Native
const devices = await deviceClient.webAuthn.get();

devices.forEach((device) => {
    console.log('id:', device.id);
    console.log('deviceName:', device.deviceName);
    console.log('uuid:', device.uuid);
    console.log('createdDate:', new Date(device.createdDate).toISOString());
    console.log('lastAccessDate:', new Date(device.lastAccessDate).toISOString());
    console.log('credentialId:', device.credentialId);
    console.log('---');
  });
Listing bound devices on React Native
const devices = await deviceClient.bound.get();

  devices.forEach((device) => {
    console.log('id:           ', device.id);
    console.log('deviceName:   ', device.deviceName);
    console.log('uuid:         ', device.uuid);
    console.log('deviceId:     ', device.deviceId);
    console.log('createdDate:  ', new Date(device.createdDate).toISOString());
    console.log('lastAccessDate:', new Date(device.lastAccessDate).toISOString());
    console.log('---');
  });
Listing profiled devices on React Native
const devices = await deviceClient.profile.get();

  devices.forEach((device) => {
    console.log('id:               ', device.id);
    console.log('deviceName:       ', device.deviceName);
    console.log('identifier:       ', device.identifier);
    console.log('metadata:         ', JSON.stringify(device.metadata, null, 2));
    console.log('location:         ', device.location
      ? `lat ${device.location.latitude}, lon ${device.location.longitude}`
      : 'none');
    console.log('lastSelectedDate: ', new Date(device.lastSelectedDate).toISOString());
    console.log('---');
  });
Listing Push devices on React Native
const devices = await deviceClient.push.get();

  devices.forEach((device) => {
    console.log('id:           ', device.id);
    console.log('deviceName:   ', device.deviceName);
    console.log('uuid:         ', device.uuid);
    console.log('createdDate:  ', new Date(device.createdDate).toISOString());
    console.log('lastAccessDate:', new Date(device.lastAccessDate).toISOString());
    console.log('---');
  });
Listing OATH devices on React Native
const devices = await deviceClient.oath.get();

  devices.forEach((device) => {
    console.log('id:           ', device.id);
    console.log('deviceName:   ', device.deviceName);
    console.log('uuid:         ', device.uuid);
    console.log('createdDate:  ', new Date(device.createdDate).toISOString());
    console.log('lastAccessDate:', new Date(device.lastAccessDate).toISOString());
    console.log('---');
  });

Renaming devices

Use the update() method to rename a registered device and save the change to the server.

Obtain the device object from get(), set the new deviceName, and pass it to update(). update() returns a Promise that resolves with the updated device object.

  • Bound devices

  • OATH devices

Renaming a bound device on React Native
const devices = await deviceClient.bound.get();
const device = devices[0];

const updatedDevice = await deviceClient.bound.update({
  ...device,
  deviceName: 'My Updated Device Name',
});

console.log('Updated bound device:', updatedDevice);
Renaming OATH devices on React Native
const devices = await deviceClient.oath.get();
const device = devices[0];

const updatedDevice = await deviceClient.oath.update({
  ...device,
  deviceName: 'Work Authenticator',
});

console.log('Updated OATH device:', updatedDevice);

Deleting devices

Use the delete() method to delete a device from the user’s profile.

The authentication journey that provided the user’s session must meet one or more of the following criteria:

  • Used the same multi-factor authentication method as the device you want to delete.

    For example, to delete a WebAuthn device, the authentication journey that created the session must also have authenticated using a WebAuthn device.

  • Used the Enable Device Management node that alters the Device Check Enforcement Strategy.

Obtain the device object from get(), and then pass it to delete(). The delete() function returns a Promise that resolves with the deleted device object.

  • Push devices

  • WebAuthn devices

Deleting a Push authenticator device on React Native
const devices = await deviceClient.push.get();
const device = devices[0];

await deviceClient.push.delete(device);
console.log('Push device deleted');
Deleting a WebAuthn device on React Native
const devices = await deviceClient.webAuthn.get();
const device = devices[0];

await deviceClient.webAuthn.delete(device);
console.log('WebAuthn device deleted');

Handling errors

All device client operations throw a DeviceClientError when they fail.

DeviceClientError extends the base PingError class and exposes a code property you can use to identify the cause and take appropriate action, such as redirecting to login when a token expires.

The following code shows how to handle errors from a device operation:

Handling errors on React Native
import { DeviceClientError } from '@ping-identity/rn-device-client';

try {
  const devices = await deviceClient.oath.get();
} catch (error) {
  if (error instanceof DeviceClientError) {
    switch (error.code) {
      case 'DEVICE_CLIENT_INVALID_TOKEN':
        // SSO token is missing, expired, or rejected — re-authenticate
        break;
      case 'DEVICE_CLIENT_NETWORK_ERROR':
        // Network connectivity failure
        break;
      case 'DEVICE_CLIENT_NOT_FOUND':
        // The requested device does not exist on the server
        break;
      default:
        console.error('Device operation failed:', error.message);
    }
  }
}

The module returns the following error codes:

Error code Description

DEVICE_CLIENT_ERROR

Generic or unknown error.

DEVICE_CLIENT_NETWORK_ERROR

Network connectivity failure.

DEVICE_CLIENT_REQUEST_FAILED

The server returned a non-success HTTP status.

DEVICE_CLIENT_INVALID_TOKEN

The SSO token is missing, expired, or rejected by the server.

Obtain a fresh token by triggering a new authentication journey.

DEVICE_CLIENT_DECODING_FAILED

The native bridge could not parse the server response.

DEVICE_CLIENT_MISSING_CONFIG

Required configuration fields were not provided to createDeviceClient().

DEVICE_CLIENT_NOT_FOUND

The requested device does not exist on the server.

DEVICE_CLIENT_HANDLE_NOT_FOUND

The client has already been disposed.

Call createDeviceClient() again to obtain a new client instance.