Device Fingerprint
MOBILE

React Native

This guide shows you how to integrate GeelabGuard into a React Native app, initialize the native SDK, and generate a device receipt that can be sent to your business backend.

Overview

geelabguard-rn-plugin supports both the React Native Legacy Architecture and New Architecture through the same Promise-based API. After completing this guide, you will be able to:

  1. Install the React Native plugin and the separately licensed native SDKs.
  2. Initialize GeelabGuard with an AppID.
  3. Generate a local receipt or submit a receipt when a business event occurs.
  4. Send the token securely to your business backend.

This guide covers only the React Native client integration. Receipt verification, risk decisions, and business actions must be handled by your backend.

Prerequisites

Before you begin, make sure that:

  • You have a working React Native development environment.
  • Your React Native version is 0.71.0 or later.
  • Your Android app uses minSdkVersion 21 or later.
  • Your iOS app has a minimum deployment target of iOS 12.4 or later.
  • You have obtained an AppID through an authorized GeelabGuard channel.
  • You have obtained the native SDK for each target platform through an authorized GeelabGuard channel:
PlatformNative SDKRelative installation path in the npm package
Androidgeelabguard_android_vx.y.z_date.aarandroid/libs/geelabguard_android_vx.y.z_date.aar
iOSGeelabGuardSDK.xcframework x.y.zios/Frameworks/GeelabGuardSDK.xcframework

The native SDK binaries are not included in the GitHub repository or npm package. React Native Web is not supported.

1. Prepare a React Native project

If you already have a React Native project, continue to the next section. Otherwise, create one with the React Native Community CLI:

npx @react-native-community/cli init GeelabGuardRN
cd GeelabGuardRN

Run the app before adding the plugin to confirm that your React Native environment works correctly:

npx react-native start

In another terminal, run the target platform:

# Android
npx react-native run-android

# iOS
npx react-native run-ios

2. Install the React Native plugin

Run the following command from the application root:

npm install geelabguard-rn-plugin

If you use Yarn:

yarn add geelabguard-rn-plugin

3. Install the native SDKs

Install only the native SDKs for the platforms that your application builds.

Android

Copy the licensed AAR into the plugin's android/libs directory:

mkdir -p node_modules/geelabguard-rn-plugin/android/libs
cp /path/to/geelabguard_android_vx.y.z_date.aar \
  node_modules/geelabguard-rn-plugin/android/libs/

The plugin checks for this file during Gradle configuration. If the file is missing, the build stops and displays the expected path.

The native SDK manifest declares android.permission.INTERNET. The plugin's consumer ProGuard rules preserve the tech.geelab.core and tech.geelab.geegateway namespaces.

iOS

Copy the licensed XCFramework into the plugin's ios/Frameworks directory, then install the Pods:

mkdir -p node_modules/geelabguard-rn-plugin/ios/Frameworks
cp -R /path/to/GeelabGuardSDK.xcframework \
  node_modules/geelabguard-rn-plugin/ios/Frameworks/

cd ios
pod install
cd ..

The plugin's podspec checks this directory during CocoaPods resolution and automatically adds the required -ObjC linker flag.

Reinstalling, pruning, or rebuilding node_modules may remove native SDKs that were copied manually. If this happens, copy the SDKs again and rebuild the native app.

4. Initialize the SDK

Before calling any other API, initialize GeelabGuard with the AppID (public_key) obtained from the dashboard:

import { GeelabGuard } from 'geelabguard-rn-plugin';

await GeelabGuard.initialize('your-app-id');

When serverUrl is omitted, the native SDK uses the default global service endpoint. If the AppID belongs to a specific Region, pass the reporting endpoint configured for that Region:

await GeelabGuard.initialize(
  'your-app-id', // public_key obtained from the dashboard
  'https://riskct-eu.geelabapi.com/api/v2/client_report'
);

Neither appId nor an explicitly provided serverUrl can be an empty string. The AppID and service endpoint must belong to the same configured Region.

5. Generate and submit a device receipt

Submit online

For most business scenarios that require a server response, call submitReceipt:

const receipt = await GeelabGuard.submitReceipt('business-request-id');

// Send respondedGeeToken to your business backend for verification and risk processing.
const token = receipt.respondedGeeToken;

signData binds the receipt to the current business request. You can use a request identifier generated by your business system. Do not pass passwords, private keys, or other sensitive plaintext values.

Generate a local receipt only

When you do not need to submit data to the server immediately, call fetchReceipt:

const receipt = await GeelabGuard.fetchReceipt('business-request-id');

// Send geeToken to your business backend.
const token = receipt.geeToken;

signData must be a string. Pass an empty string if your business flow does not need to bind any data.

6. Add a minimal working example

The following App.tsx example initializes the SDK when the page loads and submits a device receipt when the user selects the button. The example displays only the operation status and does not expose the token in the UI or logs.

import { useEffect, useState } from 'react';
import { Button, SafeAreaView, StyleSheet, Text } from 'react-native';
import { GeelabGuard, GeelabGuardError } from 'geelabguard-rn-plugin';

const APP_ID = 'your-app-id'; // public_key obtained from the dashboard

export default function App() {
  const [initialized, setInitialized] = useState(false);
  const [status, setStatus] = useState('Initializing GeelabGuard…');

  useEffect(() => {
    let active = true;

    GeelabGuard.initialize(APP_ID).then(
      () => {
        if (!active) return;
        setInitialized(true);
        setStatus('GeelabGuard initialized');
      },
      (error: unknown) => {
        if (!active) return;
        setStatus(
          error instanceof GeelabGuardError
            ? `Initialization failed: ${error.code}`
            : 'Initialization failed'
        );
      }
    );

    return () => {
      active = false;
    };
  }, []);

  const identifyDevice = async () => {
    setStatus('Generating device receipt…');

    try {
      const receipt = await GeelabGuard.submitReceipt('business-request-id');
      const token = receipt.respondedGeeToken;
      if (!token) throw new Error('The response does not contain respondedGeeToken');

      // Call your own HTTPS business API here and send the token to your backend.
      // Do not store server private keys on the client or trust client-side risk results directly.
      setStatus('Device receipt generated; send it to your business backend');
    } catch (error) {
      if (error instanceof GeelabGuardError) {
        // For network or service errors, error.receipt may contain a local geeToken for fallback use.
        setStatus(`Generation failed: ${error.code}`);
        return;
      }
      setStatus('Generation failed: unknown error');
    }
  };

  return (
    <SafeAreaView style={styles.container}>
      <Text style={styles.status}>{status}</Text>
      <Button
        title="Generate device receipt"
        disabled={!initialized}
        onPress={identifyDevice}
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 24,
  },
  status: {
    marginBottom: 16,
  },
});

In a real project, replace your-app-id and business-request-id with your own configuration and business request identifier, then connect your HTTPS backend API at the indicated location.

7. Run and verify

After installing or changing native dependencies, rebuild the application. Refreshing JavaScript alone does not load new native modules.

Start Metro:

npx react-native start

In another terminal, run the target platform:

# Android
npx react-native run-android

# iOS
npx react-native run-ios

Verify the integration in this order:

  1. The application completes a native build and starts successfully.
  2. GeelabGuard.initialize completes successfully.
  3. Selecting Generate device receipt causes submitReceipt to return a receipt.
  4. The application sends respondedGeeToken to your business backend over HTTPS according to your API contract.
  5. The business backend verifies the token and makes a risk decision.

To check the installed native SDK version, call:

const version = await GeelabGuard.getVersion();

Receipt fields

type GeelabGuardReceipt = {
  appId: string | null;
  geeToken: string | null;
  geeId: string | null;
  geeIdTimestamp: string | null;
  respondedGeeToken: string | null;
  originalResponseBase64: string | null;
};
  • geeToken: A locally generated token that can be used for the local receipt flow or as a fallback after a network failure.
  • respondedGeeToken: The token returned by the server after a successful submission. It is typically sent to your business backend for further processing.
  • The other fields support correlation and diagnostics. Use them according to your GeelabGuard server integration plan.
  • originalResponseBase64 is a Base64 representation of the raw binary response. Decode it only when required in a controlled diagnostic process.

Do not expose the AppID, signData, tokens, or originalResponseBase64 in production logs, analytics platforms, or the user interface.

Error handling

The plugin normalizes errors as GeelabGuardError:

import { GeelabGuard, GeelabGuardError } from 'geelabguard-rn-plugin';

try {
  const receipt = await GeelabGuard.submitReceipt('business-request-id');
  // Send receipt.respondedGeeToken securely to your business backend.
} catch (error) {
  if (error instanceof GeelabGuardError) {
    const fallbackGeeToken = error.receipt?.geeToken;
    // Decide whether to use fallbackGeeToken according to error.code and your business policy.
  }
}
Error codeMeaning
INVALID_ARGUMENTThe AppID, service endpoint, or another argument is invalid.
NOT_INITIALIZEDThe SDK has not been initialized, or the native SDK did not return a receipt.
NETWORK_ERRORA network error occurred during native submission.
INVALID_RESPONSEThe service response format is invalid.
SERVICE_FAILUREThe server reported a processing failure.
UNKNOWN_NATIVE_ERRORThe native SDK returned an unclassified error.

For NETWORK_ERROR, INVALID_RESPONSE, or SERVICE_FAILURE, the error may contain a receipt with a local geeToken. Your backend and business policy should determine whether to use that token as a fallback.

Frequently asked questions

The Android build reports a missing SDK

Confirm that the file is located at:

node_modules/geelabguard-rn-plugin/android/libs/geelabguard_android_vx.y.z_date.aar

If you recently reinstalled the dependencies, copy the AAR again and rebuild the app.

pod install reports a missing SDK on iOS

Confirm that the directory is located at:

node_modules/geelabguard-rn-plugin/ios/Frameworks/GeelabGuardSDK.xcframework

Run pod install again, then rebuild the iOS application.

GeelabGuard is not linked appears

Confirm that the native dependencies are installed, then perform a complete rebuild of the Android or iOS application. Refreshing Metro or reloading JavaScript cannot link a native module.

iOS reports duplicate symbols

Do not declare another Objective-C class named GeelabGuard in the host application. The native SDK already exports this class. The React Native bridge is registered internally as RNGeelabGuard, while the JavaScript module name remains GeelabGuard.

A receipt cannot be obtained

Wait for GeelabGuard.initialize to complete successfully before calling fetchReceipt or submitReceipt. If you provide a regional service endpoint, confirm that it belongs to the same Region as the AppID.

Production checklist

  • The native SDKs come from an authorized channel, and their versions match the plugin requirements.
  • The AppID matches the regional service endpoint.
  • Tokens are sent only to a trusted business backend over HTTPS.
  • Server private keys and risk-decision logic are not stored in the React Native client.
  • Production logs do not record the AppID, signData, tokens, or raw responses.

Next steps

  • Choose fetchReceipt or submitReceipt according to your business scenario.
  • Receive the token in your business backend, then implement verification, risk decisions, and fallback policies.