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
| Environment | URL |
|---|---|
| Sandbox | https://d.sandbox.viewpkg.com/device_scan/token |
| Production | https://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..."
}
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.
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.
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.