Device Fingerprint
MOBILE

Flutter

This guide shows you how to integrate geelabguard_flutter into a Flutter application and generate and submit device fingerprint receipts.

This guide covers client-side integration only. Your backend must continue processing the originalResponse returned by submitReceipt according to your GeelabGuard integration protocol. The plugin does not replace server-side queries, signature verification, or risk decisions.

Prerequisites

Before you begin, make sure you have:

  • Flutter SDK 3.10.0 or later
  • Dart 3.0.5 or later
  • A valid GeelabGuard AppID
  • Android Studio and the Android SDK, or Xcode, depending on the target platform
  • A working knowledge of Dart and Flutter development

Android API level 19 is the minimum supported version, and the plugin's native iOS layer supports iOS 11.0 or later. The effective minimum iOS version also depends on the Flutter SDK in use; the example application in this repository targets iOS 15.0 with the current Flutter stable release. Testing on a physical device also requires device trust, Developer Mode, and code-signing configuration.

1. Add the plugin

Add the dependency to your application's pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  geelabguard_flutter: ^1.0.1

Then fetch the dependency:

flutter pub get

To run the example application included in the plugin repository, you can use a path dependency to test the local source:

dependencies:
  geelabguard_flutter:
    path: ../

2. Configure Android

The plugin bundles the precompiled Android SDK, including the JAR and JNI libraries for four ABIs. Integrators do not need to compile C/C++ source code or install or pin an NDK version specifically for this plugin.

The plugin does not declare a fixed ndkVersion; the host project and Flutter toolchain manage it. If another dependency requires a specific NDK version, follow the build diagnostics and configure the host project with the highest version required by all dependencies.

The plugin already declares the Android INTERNET permission.

3. Configure iOS

From the Flutter project directory, install the CocoaPods dependencies:

cd ios
pod install
cd ..

You can also run flutter run, which normally invokes pod install automatically. To debug with Xcode, open the workspace instead of the project:

open -a Xcode ios/Runner.xcworkspace

In Xcode, select the Runner target, configure the Team and a unique Bundle Identifier under Signing & Capabilities, and then run the application on a simulator or physical device. A physical device must have Developer Mode enabled and trust the current Mac, and your Xcode version must support the device's iOS version.

4. Register the AppID

Call register during application startup or before the first use. Registration must complete successfully before you call fetchReceipt or submitReceipt:

import 'package:geelabguard_flutter/geelabguard_flutter.dart';

Future<void> initializeGeelabGuard() async {
  await GeelabGuard.register('YOUR_GEELABGUARD_APP_ID');
}

Use a custom service endpoint (optional)

If your deployment must override the native SDK's default service endpoint, pass serverUrl during registration:

await GeelabGuard.register(
  'YOUR_GEELABGUARD_APP_ID', // public_key obtained from the dashboard
  serverUrl: 'https://riskct-global.geelabapi.com/api/v2/client_report',
);

The plugin passes serverUrl to the native registration APIs on both Android and iOS. When the argument is omitted, each platform SDK continues to use its built-in default endpoint.

The Dart layer validates this value. It must be an http or https URL with a host. An empty or malformed value throws an ArgumentError before the native registration method is invoked. Refer to the GeelabGuard native SDK integration documentation to determine whether the URL must include the full API path.

Because register is asynchronous, wait for it to complete in main:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await GeelabGuard.register(
    'YOUR_GEELABGUARD_APP_ID', // public_key obtained from the dashboard
    // Optional: override the native SDK's default service endpoint.
    serverUrl: 'https://riskct-global.geelabapi.com/api/v2/client_report',
  );
  runApp(const MyApp());
}

Replace the placeholder with your actual AppID. Do not commit production AppIDs, business secrets, or server-side credentials to a public repository.

5. Generate a local receipt

fetchReceipt generates a receipt locally without submitting it:

final receipt = await GeelabGuard.fetchReceipt('YOUR_BUSINESS_DATA');

if (receipt != null) {
  print('GeeID: ${receipt.geeID}');
  print('GeeToken: ${receipt.geeToken}');
  print('GeeIDTimestamp: ${receipt.geeIDTimestamp}');
}

The SDK uses data for signature verification and does not submit its plaintext value. Use a transaction ID or credential that can correlate the current business operation, and do not include passwords, keys, or other sensitive data.

6. Submit a receipt

submitReceipt generates and submits a receipt. Timeout values are expressed in milliseconds, with a default of 5,000 milliseconds:

final receipt = await GeelabGuard.submitReceipt(
  'YOUR_BUSINESS_DATA',
  timeoutMilliseconds: 5000,
);

if (receipt != null) {
  print('GeeID: ${receipt.geeID}');
  print('RespondedGeeToken: ${receipt.respondedGeeToken}');
  print('OriginalResponse: ${receipt.originalResponse}');
}

For example, set the timeout to 10 seconds as follows:

await GeelabGuard.submitReceipt(
  'YOUR_BUSINESS_DATA',
  timeoutMilliseconds: 10000,
);

7. Handle errors

Native SDK errors are returned as PlatformException. Calling a receipt method before registration throws GeelabGuardException. Catch both exception types at your business entry point:

import 'package:flutter/services.dart';

Future<void> submit() async {
  try {
    final receipt = await GeelabGuard.submitReceipt('YOUR_BUSINESS_DATA');
    // Pass the receipt result to your business workflow.
    print(receipt?.toDisplayText());
  } on GeelabGuardException catch (error) {
    print('Invalid GeelabGuard call sequence: ${error.message}');
  } on PlatformException catch (error) {
    print('GeelabGuard native error: ${error.code} ${error.message}');
    // For Android submission errors, error.details['code'] may contain the SDK error code.
  }
}

8. Run the example application

The repository includes a complete demo in example/:

cd example
flutter pub get
flutter devices
flutter run -d <device-id>

Before running the demo, edit example/lib/main.dart and replace mGeelabGuardAppID with your actual AppID. Select the controls in this order:

  1. Register
  2. Fetch Receipt
  3. Submit Receipt

The Chrome and macOS desktop targets cannot exercise the native Android or iOS SDK. Use an Android physical device or emulator, or an iOS simulator or physical device.

Verification checklist

  • After Register succeeds, GeelabGuard.isRegistered is true.
  • Fetch Receipt returns appID, geeToken, geeID, and geeIDTimestamp.
  • Submit Receipt returns respondedGeeToken or originalResponse.
  • Business data is non-empty, and all timeout values are passed in milliseconds.
  • Calling a receipt method before registration produces an explicit call-sequence error.
  • On a physical device, error handling is verified while the device is locked, offline, or the service is unavailable.

Next steps

Integrate the GeeID, GeeToken, timestamp, and submission result into your backend workflow, then perform queries, signature verification, and risk decisions according to the GeelabGuard server-side protocol. Refer to your formal integration documentation for server endpoints, authentication, and response fields.