---
title: Integrating FIDO auth journeys in React Native
description: Integrate FIDO authentication into React Native apps using the FIDO module to register authenticators and handle WebAuthn journeys
component: orchsdks
page_id: orchsdks:journey:use-cases/fido/react-native/react-native-fido-auth-journey
canonical_url: https://developer.pingidentity.com/orchsdks/journey/use-cases/fido/react-native/react-native-fido-auth-journey.html
llms_txt: https://developer.pingidentity.com/orchsdks/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
revdate: Fri, 12 Jun 2026 14:14:33 +0100
keywords: ["FIDO", "WebAuthn", "MFA", "Hardware", "Source Code", "Integration", "SDK", "React Native"]
section_ids:
  step_1_installing_modules: Step 1. Installing modules
  installing_native_dependencies_on_ios: Installing native dependencies on iOS
  adding_optional_dependencies_on_android: Adding optional dependencies on Android
  step_2_creating_the_fido_client: Step 2. Creating the FIDO client
  choosing_the_fido2_backend_on_android: Choosing the FIDO2 backend on Android
  configuration_options: Configuration options
  step_3_registering_fido_authenticators: Step 3. Registering FIDO authenticators
  registerforjourney_options: registerForJourney options
  step_4_authenticating_using_fido: Step 4. Authenticating using FIDO
  authenticateforjourney_options: authenticateForJourney options
  step_5_handling_cancellation_and_errors: Step 5. Handling cancellation and errors
  error_codes: Error codes
---

# Integrating FIDO auth journeys in React Native

[icon: circle-check, set=far]PingOne Advanced Identity Cloud [icon: circle-check, set=far]PingAM [icon: react, set=fab]React Native

The FIDO module provides native-backed FIDO capabilities for React Native apps.

|   |                                                                                                                                                          |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Before you beginEnsure you have [prepared for FIDO authentication in React Native apps](before-you-begin.html) before attempting the steps on this page. |

## Step 1. Installing modules

The FIDO module requires `@ping-identity/rn-core` as a peer dependency.

Ensure it is installed before proceeding:

* yarn

* npm

```shell
yarn add @ping-identity/rn-core
```

```shell
npm install @ping-identity/rn-core
```

Then install the FIDO module:

* yarn

* npm

```shell
yarn add @ping-identity/rn-fido
```

```shell
npm install @ping-identity/rn-fido
```

The FIDO module works alongside the Journey module.

Optionally, install the Journey module if you have not already added it:

* yarn

* npm

```shell
yarn add @ping-identity/rn-journey
```

```shell
npm install @ping-identity/rn-journey
```

### Installing native dependencies on iOS

After installing the package, install the native iOS dependencies using CocoaPods:

```shell
cd ios && pod install
```

### Adding optional dependencies on Android

Gradle resolves the Android native dependencies automatically.

Optionally, add the following dependencies to your app's `build.gradle` if needed:

* If your app targets Android API 33 (Android 13) or older, add `androidx.credentials:credentials-play-services-auth` to ensure FIDO functions correctly on those devices.

* If your app needs to support non-discoverable FIDO credentials or physical security keys, add `com.google.android.gms:play-services-fido`.

## Step 2. Creating the FIDO client

Create a FIDO client by calling `createFidoClient()`.

Create the client once and reuse it for the lifetime of the relevant screen or session:

Creating the FIDO client

```typescript
import { createFidoClient } from '@ping-identity/rn-fido';

const fidoClient = createFidoClient();
```

### Choosing the FIDO2 backend on Android

On Android, the FIDO client supports two underlying credential APIs. By default, the native SDK auto-detects which to use at runtime.

You can override this using the `android.useFido2Client` option:

* Set `useFido2Client: false` to force the Credential Manager API, recommended for applications targeting Android 14 (API 34) and later.

* Set `useFido2Client: true` to force the legacy Google Play Services FIDO2 Client API, for devices running Android 13 or older.

Overriding the FIDO2 backend on Android

```typescript
const fidoClient = createFidoClient({
  android: {
    useFido2Client: false,
  },
});
```

### Configuration options

| Option                   | Required | Description                                                                                                                                                                                     |
| ------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `android.useFido2Client` | No       | When omitted, the native SDK auto-detects the appropriate API at runtime. Set `false` to force the Credential Manager API, or `true` to force the legacy Google Play Services FIDO2 Client API. |
| `logger`                 | No       | Logger instance from `@ping-identity/rn-logger`. Logging is suppressed when omitted.                                                                                                            |

## Step 3. Registering FIDO authenticators

When the journey encounters a [WebAuthn Registration node](https://docs.pingidentity.com/auth-node-ref/latest/webauthn-registration.html), the client receives a `FidoRegistrationCallback`.

On receipt, call `registerForJourney()` on the FIDO client. The method invokes the platform authenticator UI and populates the callback output before returning:

Registering a FIDO authenticator in a journey node

```typescript
import { useJourney } from '@ping-identity/rn-journey';

function FidoRegistrationNode({ journeyClient }) {
  const [node, { next }] = useJourney(journeyClient);

  const registrationCallback = node?.callbacks?.find(
    (cb) => cb.type === 'FidoRegistrationCallback',
  );

  if (!registrationCallback) return null;

  async function handleRegister() {
    await fidoClient.registerForJourney(journeyClient, {
      deviceName: 'My device',
    });
    await next({});
  }
}
```

The `journeyClient` parameter is a journey client created with `createJourneyClient()`. Learn more in [Configuring a Journey client in React Native](../../../usage/react-native/03-configuring-the-journey-module.html).

|   |                                                                                                                                                                                                                         |
| - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | FIDO Registration nodes are commonly configured to collect a device name from the user before committing the credential.Collect the name before calling `registerForJourney()`, and pass it in the `deviceName` option. |

### `registerForJourney` options

| Option       | Required | Description                                                                                                                               |
| ------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `deviceName` | No       | A human-readable label for the credential stored on the server. When omitted the server applies its default naming policy.                |
| `index`      | No       | Zero-based index of the `FidoRegistrationCallback` within the current node, used when a node carries more than one registration callback. |

## Step 4. Authenticating using FIDO

When the journey encounters a [WebAuthn Authentication node](https://docs.pingidentity.com/auth-node-ref/latest/webauthn-authentication.html), the client receives a `FidoAuthenticationCallback`.

On receipt, call `authenticateForJourney()` on the FIDO client. The method presents the platform authenticator UI, signs the server's challenge, and populates the callback output before returning:

Authenticating with FIDO in a journey node

```typescript
import { useJourney } from '@ping-identity/rn-journey';

function FidoAuthenticationNode({ journeyClient }) {
  const [node, { next }] = useJourney(journeyClient);

  const authCallback = node?.callbacks?.find(
    (cb) => cb.type === 'FidoAuthenticationCallback',
  );

  if (!authCallback) return null;

  async function handleAuthenticate() {
    await fidoClient.authenticateForJourney(journeyClient);
    await next({});
  }
}
```

The `journeyClient` parameter is a journey client created with `createJourneyClient()`. Learn more in [Configuring a Journey client in React Native](../../../usage/react-native/03-configuring-the-journey-module.html).

### `authenticateForJourney` options

| Option  | Required | Description                                                                                                                                   |
| ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `index` | No       | Zero-based index of the `FidoAuthenticationCallback` within the current node, used when a node carries more than one authentication callback. |

## Step 5. Handling cancellation and errors

When a FIDO operation fails or is cancelled, the SDK throws a `FidoError`.

Use the `code` property to distinguish cancellation from other failures.

The following example extends `handleAuthenticate` from the previous step with error handling:

Handling FIDO cancellation and errors

```typescript
import { FidoError } from '@ping-identity/rn-fido';

async function handleAuthenticate() {
  try {
    await fidoClient.authenticateForJourney(journey);
  } catch (err) {
    if (err instanceof FidoError) {
      if (err.code === 'FIDO_AUTHENTICATE_CANCELLED') {
        // Non-fatal — offer a fallback path and stop here
        return;
      }
      // For other errors, fall through and advance the journey
      // so the server can route to its configured failure branch
    }
  }
  await next({});
}
```

### Error codes

| Error code                    | Description                                                                                                                   |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `FIDO_ERROR`                  | A general FIDO error that does not fall into a more specific category.                                                        |
| `FIDO_REGISTER_ERROR`         | Registration failed. The platform reported an error creating the credential.                                                  |
| `FIDO_AUTHENTICATE_ERROR`     | Authentication failed due to a platform or server-side error.                                                                 |
| `FIDO_AUTHENTICATE_CANCELLED` | The user explicitly dismissed the biometric prompt. You can treat this as non-fatal and offer a fallback authentication path. |
| `FIDO_ACTIVITY_UNAVAILABLE`   | The Android Activity required to launch the FIDO UI is unavailable.                                                           |
| `FIDO_WINDOW_UNAVAILABLE`     | The iOS window required to present the FIDO UI is unavailable.                                                                |
| `FIDO_CALLBACK_NOT_FOUND`     | The module could not find the requested callback index in the current journey node.                                           |
