Skip to main content

Implementation

Prerequisite: obtaining the token

The startDeviceScan function requires a token. This token is temporary and must be generated on your backend through a server-to-server request to our API, before calling the SDK function.

Endpoint

EnvironmentURL
Sandboxhttps://d.sandbox.viewpkg.com/device_scan/token
Productionhttps://d.viewpkg.com/device_scan/token

Request

Method: POST

Headers:

{
"Authorization": "YOUR_DEVICE_SCAN_API_KEY"
}

Body:

{
"session_id": "unique_session_id"
}

Response

The successful response contains the token that must be passed to the startDeviceScan function.

{
"token": "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6..."
}
Important Note!

The Device Scan API key must never be embedded in the application. The request above must come exclusively from your backend. The session_id used to generate the token must be the same one passed to the startDeviceScan function.

note

Device scan can be executed asynchronously. Therefore, there is no need to block the UI to wait for the Promise resolution. The user is able to interact with the app normally while device scan is being processed in the background.

note

We suggest that device scan is executed as soon as possible — for example, inside a useEffect. Since it may need more execution time to collect all data, this early call ensures the most complete device information is extracted.

Function signature

await startDeviceScan(
token, // string - token obtained from the API
document_number, // string - the user's CPF
session_id, // string - session identifier
event_id, // string - event identifier
event_type, // string - event type (e.g. 'onboarding')
environment // CAAS_ENVIRONMENT.SANDBOX or CAAS_ENVIRONMENT.PRODUCTION
);

See The startDeviceScan function for the full description of each parameter.

Complete example

import * as React from 'react';
import { useCallback, useEffect } from 'react';
import { View, Button, Platform, PermissionsAndroid, Permission } from 'react-native';
import { request, PERMISSIONS, RESULTS } from 'react-native-permissions';
import { CAAS_ENVIRONMENT, startDeviceScan } from '@qitech/react-native-device-scan';

const DEVICE_SCAN_API_URL = 'https://d.sandbox.viewpkg.com/device_scan/token';
const DEVICE_SCAN_API_KEY = '<DEVICE_SCAN_API_KEY>';

const config = {
environment: CAAS_ENVIRONMENT.SANDBOX,
sessionId: '<SESSION_ID>',
documentNumber: '<CPF_NUMBER>',
deviceScanEventId: '1',
deviceScanEventType: 'onboarding',
};

export default function App() {
// Step 1: request the permissions that broaden the collection
const requestDeviceScanPermissions = async (): Promise<boolean> => {
if (Platform.OS === 'ios') {
const result = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
return result === RESULTS.GRANTED;
}

const permissionsToRequest: Permission[] = [
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE,
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
];

// BLUETOOTH_CONNECT is only needed on Android 12+ (API 31+)
if (Platform.Version >= 31) {
permissionsToRequest.push('android.permission.BLUETOOTH_CONNECT' as Permission);
}

const results = await PermissionsAndroid.requestMultiple(permissionsToRequest);

return (
results[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] ===
PermissionsAndroid.RESULTS.GRANTED ||
results[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION] ===
PermissionsAndroid.RESULTS.GRANTED
);
};

// Step 2: obtain the token through your backend
const fetchDeviceScanToken = useCallback(async () => {
const response = await fetch(DEVICE_SCAN_API_URL, {
method: 'POST',
headers: {
'Authorization': DEVICE_SCAN_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ session_id: config.sessionId }),
});

if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}

const data = await response.json();

if (!data.token) {
throw new Error("No 'token' found in response.");
}

return data.token;
}, []);

// Step 3: run the collection
const captureDeviceScan = async (): Promise<void> => {
try {
const deviceScanToken = await fetchDeviceScanToken();

const result = await startDeviceScan(
deviceScanToken,
config.documentNumber,
config.sessionId,
config.deviceScanEventId,
config.deviceScanEventType,
config.environment
);

console.log('Device Scan result: ' + String(result));
} catch (error) {
console.log('Error executing device scan: ' + error);
}
};

useEffect(() => {
const init = async () => {
await requestDeviceScanPermissions();
await captureDeviceScan();
};
init();
}, []);

return (
<View>
<Button title="Run Device Scan" onPress={captureDeviceScan} />
</View>
);
}

Best practices

  • Execute device scan as early as possible (for example, in a useEffect) — it needs time to collect complete device data.
  • Device scan runs asynchronously and does not block the UI. There is no need to wait for the Promise resolution before proceeding with other flows.
  • Request the permissions before calling startDeviceScan. The SDK does not request permissions on its own — it only collects what has already been granted.

Sample apps

The module repository contains two ready-to-run apps, in the examples folder:

  • QITechReactNativeExample — pure React Native
  • QITechExpoExample — Expo

In both, App_ds.tsx demonstrates Device Scan usage with @qitech/react-native-device-scan. Replace the sample API keys with your credentials. If you have not received them yet, contact suporte.caas@qitech.com.br.