Skip to main content

React Native integration

This guide describes SDK installation in your React Native application, followed by photo capture and upload. See the overview to obtain the package, SDK key and environment URLs.

Prerequisites​

  • React Native 0.72 or later, with its Android and iOS build tools.
  • CocoaPods for iOS installation, and Xcode for signing and running on a device.
  • A physical device to validate the production workflow.
  • The certificall-mobile-sdk-react-native-<version>.tgz package provided by Certificall.

With Expo, use a development build (expo prebuild). Expo Go cannot load the SDK.

1. Install the package​

Copy the delivered file to vendor/, then declare the dependency:

{
"dependencies": {
"certificall-mobile-sdk-react-native": "file:./vendor/certificall-mobile-sdk-react-native-<version>.tgz"
}
}
npm install

The package contains the native iOS and Android SDK. No special .npmrc or Metro configuration is needed for the .tgz package.

2. Configure iOS​

React Native autolinking detects the module. Install pods from the iOS directory:

cd ios
pod install

If autolinking does not detect the module, add this declaration to your Podfile, then run pod install again:

pod 'CertificallTrustRN', :path => '../node_modules/certificall-mobile-sdk-react-native'

Add usage descriptions to Info.plist:

<key>NSCameraUsageDescription</key>
<string>Required to capture certified photos.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Required to certify the photo's location.</string>
<key>NSMotionUsageDescription</key>
<string>Required to collect motion during capture.</string>

Capture does not require photo library permission. In Xcode, select your application's Team and Bundle Identifier under Signing & Capabilities, then rebuild the application.

3. Configure Android​

Autolinking registers the module. The bridge includes the android/libs/certificall-trust-sdk.aar binary and declares its native dependencies in Gradle.

If your setup does not use autolinking, add CertificallTrustPackage to the package list in MainApplication.kt:

import com.certificall.reactnative.CertificallTrustPackage

override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply { add(CertificallTrustPackage()) }

Declare permissions in AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

The SDK includes its own file provider and the declarations needed to detect the camera. You do not need to declare a FileProvider for the SDK.

Rebuild the application after installation:

npx react-native run-android

4. Request permissions and configure the SDK​

On iOS, use the SDK helpers. On Android, use PermissionsAndroid: the SDK's request*Permission() helpers are iOS-only.

Request permissions before configuration, which starts position and motion collection. This example initializes the workflow after camera and location access have been granted.

import { PermissionsAndroid, Platform } from 'react-native';
import { CertificallTrust } from 'certificall-mobile-sdk-react-native';

export async function prepareCapture(): Promise<boolean> {
if (Platform.OS === 'android') {
const permissions = await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.CAMERA,
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
]);

const granted = PermissionsAndroid.RESULTS.GRANTED;
if (
permissions[PermissionsAndroid.PERMISSIONS.CAMERA] !== granted ||
permissions[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] !== granted
) {
return false;
}
} else {
const cameraGranted = await CertificallTrust.requestCameraPermission();
const location = await CertificallTrust.requestLocationPermission();
await CertificallTrust.requestMotionPermission();
if (!cameraGranted || location !== 'granted') return false;
}

await CertificallTrust.configure({
apiKey: '<your SDK API key>',
baseUrl: 'https://dev.certificall.app/certificall/',
appVersion: '1.0.0',
});
return true;
}

Call this preparation when your screen opens, then wait for the user's action to take the photo. appVersion is the version of your application, not the SDK.

5. Capture, then upload​

import { CertificallTrust } from 'certificall-mobile-sdk-react-native';

const photo = await CertificallTrust.takePhoto({
reportToken: 'JOB-2026-001',
metadata: { site: 'Paris', zone: 'A1' },
});

// Save this JSON to your storage before upload if the capture
// must survive the application being closed.
const serializedPhoto = JSON.stringify(photo);

const sent = await CertificallTrust.sendPhoto(photo);
console.log('Case:', sent.caseId);
console.log('PDF certificate:', sent.pdfUrl);
console.log('Warnings:', sent.warnings);

The serializedPhoto variable alone is not persistent storage. You can read the saved JSON and pass it to sendPhoto() without taking another photo. See Storage and retries.

The trust score is provided by the analysis result webhook.

API surface​

Methods are exposed on CertificallTrust.

MethodReturn valueUse
configure({ apiKey, baseUrl?, appVersion? })Promise<void>Configure and start collection.
takePhoto({ reportToken?, metadata? }?)Promise<CapturedPhoto>Local capture with its signals.
sendPhoto(photo)Promise<SentPhoto>Upload and certification.
isDebugBuild()Promise<boolean>Application build type.
requestCameraPermission()Promise<boolean>Camera permission, iOS-only.
requestLocationPermission()Promise<string>Location permission, iOS-only.
requestMotionPermission()Promise<boolean>Request motion permission, iOS-only.
getNetworkStatus()Promise<{ connected, connectionType }>Current network status.
startNetworkMonitoring(callback){ remove() }Network change notifications.
getCurrentPosition()Promise<LocationPosition>Current position.
watchPosition(callback){ remove() }Position monitoring.
getCurrentMotion()Promise<MotionData>Current motion.
watchMotion(callback){ remove() }Motion monitoring.
getDeviceSnapshot({ includeLocation?, includeMotion? }?)Promise<DeviceSnapshot>Device snapshot.

To stop a network, position or motion subscription, call its remove() method. A connected network does not guarantee a successful upload: also handle sendPhoto() errors.

Read an error​

Capture and upload errors carry a code. Additional information is in userInfo:

try {
const photo = await CertificallTrust.takePhoto();
// Save the capture before upload.
await CertificallTrust.sendPhoto(photo);
} catch (error) {
const failure = error as {
code?: string;
userInfo?: { reasons?: string[]; status?: number; reason?: string };
};
if (failure.code === 'CAPTURE_CANCELLED') {
// The user closed the camera: nothing was uploaded.
} else {
console.log(failure.code, failure.userInfo);
}
}

The error reference describes device refusals and retry conditions.

Troubleshooting​

SymptomCheck
JavaScript module not foundCheck the .tgz path in package.json, run npm install again, then restart Metro.
CertificallTrust native module is not linkedInstall pods and rebuild the native application. Check that you are not using Expo Go.
Podspec not detectedCheck CertificallTrustRN.podspec in the installed package and the Podfile declaration.
Android permission not requestedUse PermissionsAndroid, before configure().
NOT_INITIALIZEDWait for configure() to resolve before capture or upload.
DEVICE_NOT_TRUSTEDRead userInfo.reasons and device checks.
SERVER_REJECTED without a case resultCheck the key, environment, baseUrl suffix and HTTP status.
Development photo rejectedSend it to pre-production; for production, take a new photo with a distribution build.