The Device Profile module provides a structured framework for collecting device information in React Native applications. It uses a modular collector system that makes it easy to gather, extend, and customize the device data you need, with native Android and iOS collectors handling collection, permissions, and payload formatting.
This module provides two collection paths:
collectDeviceProfile for generic device profile collection.collectDeviceProfileForJourney for PingOne AIC Journey flows.Output is JSON-compatible. The exact fields are platform-defined and may vary based on collector support, permissions, and device capabilities.
Note: This module requires that the
@ping-identity/rn-coremodule is already set up and installed.
# Install & setup the core module
yarn add @ping-identity/rn-core
# Install the rn-device-profile module
yarn add @ping-identity/rn-device-profile
# If you are developing your app using iOS, run this command
cd ios && pod install
Optional integration packages:
yarn add @ping-identity/rn-logger
import { collectDeviceProfile } from '@ping-identity/rn-device-profile';
const profile = await collectDeviceProfile(['platform', 'hardware', 'network']);
{
"platform": {
"platform": "android",
"device": "flame",
"deviceName": "Pixel 4",
"model": "Pixel 4",
"brand": "google",
"locale": "en_US",
"timeZone": "America/Vancouver"
},
"hardware": {
"hardware": "flame",
"manufacturer": "Google",
"storage": 64,
"memory": 6144,
"cpu": 8,
"display": {
"width": 1080,
"height": 2280
},
"camera": {
"noOfCameras": 2
}
},
"network": {
"connected": true
},
"telephony": {
"networkCountryIso": "US",
"carrierName": "Verizon"
},
"bluetooth": {
"supported": true
},
"browser": {
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Mobile Safari/537.36"
},
"location": {
"latitude": 37.7749,
"longitude": -122.4194
}
}
Availability depends on platform and permissions.
platform: device and OS metadata.hardware: hardware and capability details.network: connection status and network properties.telephony: carrier and telephony metadata.browser: default browser user agent details.bluetooth: Bluetooth support status.location: location coordinates (requires permissions; Android needs Play Services Location).The module respects Android's permission model. Some collectors require
permissions declared in AndroidManifest.xml.
<!-- Required for NetworkCollector -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Optional: For LocationCollector (will prompt user automatically) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Note: LocationCollector handles permission requests automatically -->
LocationCollector depends on Google Play Services Location. The native module
checks for this dependency at runtime and rejects location collection if it is
missing. If your app includes location collection, add the dependency at the
app level (not in the library):
dependencies {
implementation "com.google.android.gms:play-services-location:21.3.0"
}
If you use a different version across your app, keep it consistent with the rest of your Play Services dependencies.
AndroidManifest.xml.play-services-location to your app if you use the location collector.If you use the location collector, add a location usage description to your
app's Info.plist so iOS can prompt the user for permission.
<!-- Required for LocationCollector -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app uses your location to complete device profiling.</string>
<!-- Optional: use if you need background location access -->
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app uses your location to complete device profiling.</string>
TODO: Re-check @MainActor usage in Device Profile iOS paths for potential UI-thread bottlenecks.
If you install the logger package, pass a JS logger instance per call via DeviceProfileLoggerOptions.
The logger must be created via @ping-identity/rn-logger.
If the logger package is not installed/configured, omit the logger option.
import {
collectDeviceProfile,
collectDeviceProfileForJourney,
} from '@ping-identity/rn-device-profile';
import { logger } from '@ping-identity/rn-logger';
const jsLogger = logger({ level: 'debug' });
// Pass as the last argument to any device profile call
await collectDeviceProfile(['platform', 'hardware'], { logger: jsLogger });
await collectDeviceProfileForJourney(journey, ['platform', 'hardware'], {
logger: jsLogger,
});
import { collectDeviceProfileForJourney } from '@ping-identity/rn-device-profile';
try {
await collectDeviceProfileForJourney(journey, [
'platform',
'hardware',
'network',
'location',
]);
await journey.next();
} catch (error) {
console.error('Device profile submission failed', error);
// Handle failure before advancing the Journey.
}
Note: collectDeviceProfileForJourney is only valid when a Device Profile callback
is active in the current Journey node. The native implementation resolves the
active callback, applies server-driven configuration, executes the requested
collectors, submits the resulting metadata automatically, and resolves with a
result object describing success. Failures reject with a shared GenericError.
import type {
DeviceProfile,
DeviceProfileCollector,
DeviceProfileLoggerOptions,
DeviceProfileJourneyResult,
} from '@ping-identity/rn-device-profile';
import type { JourneyInstance } from '@ping-identity/rn-types';
function collectDeviceProfile(
collectors: DeviceProfileCollector[],
options?: DeviceProfileLoggerOptions,
): Promise<DeviceProfile>;
function collectDeviceProfileForJourney(
journey: JourneyInstance,
collectors: DeviceProfileCollector[],
options?: DeviceProfileLoggerOptions,
): Promise<DeviceProfileJourneyResult>;
All promise rejections throw a DeviceProfileError instance, which extends PingError extends Error.
Use instanceof to narrow the error type:
import { DeviceProfileError } from '@ping-identity/rn-device-profile';
try {
await collectDeviceProfile(['platform']);
} catch (err) {
if (err instanceof DeviceProfileError) {
console.log(err.code, err.type, err.message);
}
}
Common error codes surfaced via error in rejection payloads:
DEVICE_PROFILE_LOCATION_UNAVAILABLE: Google Play Services Location is missing.DEVICE_PROFILE_CALLBACK_NOT_FOUND: No active Device Profile callback for the Journey.DEVICE_PROFILE_COLLECT_ERROR: Collection failed unexpectedly.MIT