@fingerly/react-native is a thin bridge to the native iOS and Android SDKs. Almost every signal worth having on a phone is out of reach of JavaScript, so the bridge calls native code rather than collecting less.
Requirements
- React Native 0.74 or newer, including the New Architecture.
- iOS 13 and Android 5.0 (API 21) or newer.
- A development build. Expo Go cannot load native modules.
Install
npm install @fingerly/react-native
cd ios && pod install
Autolinking adds the native modules. Rebuild the app after installing.
Identify a device
import { load } from '@fingerly/react-native'
// consent: 'granted' only once you have consent (or another lawful basis)
const fingerly = await load({ apiKey: 'fly_pk_production_…', consent: 'granted' })
export async function signIn(email: string, password: string) {
const { requestId } = await fingerly.identify({ tag: 'sign-in' })
return api.signIn({ email, password, requestId })
}
Send requestId to your backend with the action, and decide there after reading the stored event with a secret key. See server-side verification.
API
load(options)
apiKeystringrequiredYour public key.endpointstringA custom API origin, to which/api/v1/ingestis appended. Proxy integrations serve the browser SDK, not apps.consent'granted' | 'pending' | 'denied'Default'pending'Until it isgranted,identifyandcollectread and send nothing and throwConsentError. The state is shared by the whole app, so pass it on everyload. See consent.
identify(options)
tagstringYour own reference for this identification.submitbooleanDefaulttrueSetfalseto collect without sending.
identify resolves with the same fields as the native SDKs: requestId, visitorId, visitorIsNew, visitorConfidence, identifiable, duplicate, state, suspectScore (number | null), suspectLevel, triggers, verdicts and report. collect() returns a report without submitting. setConsent(state) changes the consent state, and consent reads it.
Deleting the stored identity
import { deleteStoredIdentity } from '@fingerly/react-native'
await deleteStoredIdentity()
Deletes the install record the native SDK keeps on the device, including the install ID the server recognises it by, for erasure requests and account deletion. It needs no load and no consent, sends nothing, and resolves once no record remains, including when there was none. It rejects with a FingerlyError when the delete fails. The next identification made with consent starts a new install ID; to stop identifying as well, set consent to 'denied' first. On iOS the record survives the app being deleted, so this is the only way to remove it. See account deletion and erasure.
Verdicts
| Verdict | Platform | What it means |
|---|---|---|
instrumentation | Both | An instrumentation toolkit is attached to the app. |
mitm | Both | Something is intercepting the app's encrypted traffic. |
automation | Both | A debugger or a test runner is driving the app. |
tampering | Both | The app's code has been hooked or modified. |
farm | Both | The device looks mass-provisioned or freshly reset. |
jailbreak, simulator | iOS | Jailbroken device; iOS Simulator. |
root, emulator, appCloner | Android | Rooted device; emulator; cloning framework. |
Verdicts a platform cannot answer are returned as { value: false, confidence: 'low', reasons: [] }, so the shape is the same on both.
Errors
import { FingerlyError } from '@fingerly/react-native'
try {
await fingerly.identify()
} catch (error) {
if (error instanceof FingerlyError && error.status === 401) {
// the key is wrong or revoked
}
}
Retries happen in the native layer. If the native module is missing, every call throws a FingerlyError that explains how to rebuild. Without consent, calls throw ConsentError, a FingerlyError whose code is consent_required.