Collecting device profiles in React Native apps
PingOne Advanced Identity Cloud PingAM React Native
This page guides you through collecting device profile data in a React Native application using @ping-identity/rn-device-profile.
It includes preconfigured collectors to collect attributes, and allows you to select which collectors to use to suit your requirements.
Step 1. Installing the module
To install the module into your React Native project, use yarn or npm as follows:
-
yarn
-
npm
yarn add @ping-identity/rn-device-profile
npm install @ping-identity/rn-device-profile
For Journey-integrated collection, also install the Journey module if you have not already done so:
-
yarn
-
npm
yarn add @ping-identity/rn-journey
npm install @ping-identity/rn-journey
After installation, import the functions you need:
import {
collectDeviceProfile,
collectDeviceProfileForJourney,
} from '@ping-identity/rn-device-profile';
import type { DeviceProfileCollector } from '@ping-identity/rn-device-profile';
Step 2. Declaring permissions
Some collectors require platform permissions. Add the necessary declarations to your project before enabling those collectors.
iOS
Open ios/<AppName>/Info.plist as source code and add the following entries as children of the top-level <dict> element:
<!-- Required for LocationCollector -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs location access to enhance security and provide personalised experiences.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs location access to enhance security and provide personalised experiences.</string>
<!-- Required for BluetoothCollector -->
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app uses Bluetooth to collect device information.</string>
Android
Open android/app/src/main/AndroidManifest.xml and add the following <uses-permission> entries inside <manifest>:
<!-- Required for LocationCollector -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Required for BluetoothCollector (Android 12+) -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- For Android 11 and earlier -->
<uses-permission android:name="android.permission.BLUETOOTH" />
|
For On iOS, |
Step 3. Collecting device profiles
Call collectDeviceProfile() with an array of collector names to gather device attributes:
import { collectDeviceProfile } from '@ping-identity/rn-device-profile';
import { logger } from '@ping-identity/rn-logger';
const profileLogger = logger({ level: 'debug' });
const profile = await collectDeviceProfile(
['platform', 'hardware', 'network'],
// Add optional logger
{ logger: profileLogger },
);
// Output collected profile JSON
console.log(JSON.stringify(profile, null, 2));
The function returns a plain JavaScript object containing the merged output of all requested collectors. Collectors that fail are omitted from the result without throwing an error.
Available collectors
| Collector value | Collector output |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Step 4. Integrating with Advanced Identity Cloud and PingAM journeys
When a journey reaches a Device Profile Collector node, the SDK receives a DeviceProfileCallback.
Call collectDeviceProfileForJourney() to collect the device signals and write them into the active journey callback, then call actions.next() to advance the node. DeviceProfileJourneyResult is an imported type that represents the resolved value from a device profile collection step inside a journey:
import { collectDeviceProfileForJourney } from '@ping-identity/rn-device-profile';
import { collectDeviceProfileForJourney } from '@ping-identity/rn-device-profile';
import type { DeviceProfileJourneyResult } from '@ping-identity/rn-device-profile';
import { useJourney, useJourneyForm } from '@ping-identity/rn-journey';
import type { JourneyClient } from '@ping-identity/rn-journey';
function useDeviceProfileNode(journeyClient: JourneyClient) {
const [node, actions] = useJourney(journeyClient);
const form = useJourneyForm(node);
const submit = async (): Promise<void> => {
const hasDeviceProfile = form.fields.some(
(f) => f.ref.type === 'DeviceProfileCallback',
);
if (!hasDeviceProfile) return;
const result: DeviceProfileJourneyResult =
await collectDeviceProfileForJourney(journeyClient, [
'platform',
'hardware',
'network',
]);
if (result.type === 'success') {
await actions.next();
}
};
|
Call |
The journey profile payload
The profile written to the journey callback includes a device identifier generated by the native platform, the collector output, and any location data. The server-side Device Profile Collector node uses the identifier field to correlate the submission with a known device:
{
"identifier": "a3f8d2...",
"metadata": {
"platform": {
"platform": "iOS",
"version": "17.0.1",
"device": "iPhone"
},
"hardware": {
"manufacturer": "Apple",
"memory": 6144,
"cpu": 6
},
"network": {
"connected": true
}
},
"location": {
"latitude": 37.2431,
"longitude": 115.7930
}
}
For details on how the device identifier is generated and how to customize it, see Customizing device identifiers in React Native apps.