Expo React Native Guide

Learn about OkHi's integration for verifying addresses.

Make sure you are running an Android Expo development build. See how to enable development builds here.

Installation

To install the OkHi React Native library run the command bellow

npx expo install react-native-webview react-native-okhi@beta

Android

Enable Expo Android Development build

If you haven't done this already, make sure you are running an android development build. You can achieve this by running the bellow command in your projects root directory.

npx expo run:android

At this point you should be able to navigate to android/

Configuration

Permissions

Add the following permissions to your AndroidManifest.xml located under android/app/src/main/AndroidManifest.xml

  • FOREGROUND_SERVICE is required if your app is targeting Android 14+

<manifest ...>
​    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" android:foregroundServiceType="location"/>
    ...
    
    <application>
    ...
    </application>

</manifest>

Maven Repo

In your android/build.gradle add the OkHi Maven repo to the list of repositories i.e

```
allprojects {
    repositories {
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android'))
        }
        maven {
            // Android JSC is installed from npm
            url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist'))
        }

        google()
        mavenCentral()
        maven { url 'https://www.jitpack.io' }
        maven { url "https://repo.okhi.io/artifactory/maven" } // <- add this
    }
}

```

iOS

Enable Expo iOS Development build

If you haven't done this already, make sure you are running a ios development build. You can achieve this by running the bellow command in your projects root directory.

npx expo run:ios

At this point you should be able to navigate to ios/

Configuration

Enable Background modes

OkHi obtains verification signals in the background, to enable this make sure to add "Location updates" and "Background fetch" to your Background Modes under Signing & Capabilities of your target.

Permissions

Add necessary permissions to your info.plist file located under /ios/MyApp

<key>NSLocationWhenInUseUsageDescription</key>
<string>String that explains why you need this permission</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>String that explains why you need this permission</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>String that explains why you need this permission</string>

AppDelegate

Open your AppDelegate.mm file located under ios/MyApp/AppDelegate.mm and add the following lines

#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <React/RCTLinkingManager.h>

// <-- import these
#import <OkHi/OkHi.h>
#import <OkHi/OkHi-Swift.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  [OkVerify startMonitoring]; // <-- add this
  self.moduleName = @"main";

  // You can add your custom initial props in the dictionary below.
  // They will be passed down to the ViewController used by React Native.
  self.initialProps = @{};

  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

Install pods

If you have your project running, stop it and run the bellow command. It'll install all the necessary pods.

npx expo run:ios

Initialisation

Add the following initialisation code to your App.js file in such a way that the code is executed whenever your app is opened.

Replace my_branch_id and my_client_key with the keys provided to you after sign up.

important: initialisation has to be done each time on app start and shouldn't have any blocking operations before it. See full integration example

import React, {useEffect} from 'react';
import {View} from 'react-native';
import * as OkHi from 'react-native-okhi';
import AddressScreen from './AddressScreen';

const App = () => {
  useEffect(() => {
    OkHi.initialize({
      credentials: {
        branchId: '', // your branch ID
        clientKey: '', // your client key
      },
      context: {
        mode: 'prod',
      },
      notification: {
        title: 'Address verification in progress',
        text: 'Tap here to view your verification status.',
        channelId: 'okhi',
        channelName: 'OkHi Channel',
        channelDescription: 'OkHi verification alerts',
      },
    })
      .then(() => console.log('init done'))
      .catch(console.log); 
  }, [])
  return (
    <View>
      <AddressScreen />
    </View>
  );
};

export default App;

Test

To confirm that initialisation is working as expected, the `init done` log should be printed out in your console every time your app is opened.

Create and verify addresses

Always use your phone number or a phone number you own during testing as a message will be sent to this number after an address is created.

We recommend that you persist the verification state of the user in your app local storage. This state can be used to ensure that a user may only verify a predefined number of addresses. Usually one address for most use cases.

Digital Verification (Default)

import React, {useState} from 'react';
import {View, Button, ActivityIndicator, ViewStyle} from 'react-native';
import {
  OkHiLocationManager,
  OkCollectSuccessResponse,
  request,
} from 'react-native-okhi';

const AddressScreen = () => {
  const [launch, setLaunch] = useState(false);
  const style: ViewStyle = {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  };

  const handleOnSuccess = async (response: OkCollectSuccessResponse) => {
    response.startVerification()
      .then(locationId => {
        console.log("started verification for: " + locationId)
        // persist response.location.id, response.user.id
      })
      .catch(error => {
        console.log(error.code)
        console.log(error.message)
      })
      .finally(() => {
        setLaunch(false);
      });
  };

  const renderLoader = () => {
    return (
      <View style={style}>
        <ActivityIndicator />
      </View>
    );
  };

  return (
    <View style={style}>
      <Button title="Create address" onPress={() => setLaunch(true)} />
      <OkHiLocationManager
        launch={launch}
        user={{
          phone: '+234xxxxx', // It is important to provide your actual phone number, as a message will be sent to this number
          firstName: 'Gift',
          lastName: 'Moore',
          email: 'giftmoore@okhi.com', // It is important to use your actual email address, an email may be sent to the provided address
        }}
        onCloseRequest={() => setLaunch(false)}
        onError={console.log}
        onSuccess={handleOnSuccess}
        config={{streetView: true}}
        loader={renderLoader()}
        theme={{
          appBar: {
            backgroundColor: '#333',
            logo: 'https://cdn.okhi.co/icon.png',
          },
          colors: {
            primary: '#333',
          },
        }}
      />
    </View>
  );
};

export default AddressScreen;

Physical Verification

If you'd like to only have physical verification done you can include verification types as part of the config object that's passed to OkHiLocationManager

<OkHiLocationManager
  ..//
  config={{verificationTypes: ["physical"]}} 
/>

Both Physical & Digital Verification

It's possible to have both physical and digital verification to run at the same time for a given address. Include both verification types as part of the array.

<OkHiLocationManager
  ..//
  config={{verificationTypes: ["physical", "digital"]}} 
/>

Server side integration

Accessing address properties

On the client/app, within your onSucess handler you can access both user and address information which you can use to transit securely to your servers. See the API reference for complete list of properties on user and location.

const handleOnSuccess = async (response: OkCollectSuccessResponse) => {
    console.log(response.user.id); // access user properties
    console.log(response.location.id); // access location properties
    await sendToServer(response.user, response.location) // send address info to your server
    await response.startVerification(); // start verification
}

Handling verification events

Once an address has been created and you've configured a webhook in the OkHi Customer Dashboard, you'll be able to receive updates regarding address verification in your backend, which you can use to enable certain services in your app. The OkHi Dashboard allows you to do much more; please see the full webhook documentation here.

Testing

Tips & Tricks

API reference found here.

Making it yours

Customise address creation experience

It is possible to completely transform the default appearance of OkHiLocationManager to better match your brand by providing values to the theme prop.

const theme = {
 colors: {primary: '#005D67'},
 appBar: {
   backgroundColor: '#005D67',
   logo: 'https://mydomain.com/logo.png'
  },
};

<OkHiLocationManager
 user={user}
 launch={launch}
 theme={theme} // customizes apperance of buttons and app bar
 style={styles.locationManager} // customizes apperance of the wrapping container
 onSuccess={handleOnSuccess}
 onCloseRequest={handleCloseRequest}
 onError={handleOnError}
/>

Customise notification icon & color

Once verification starts a persistent notification is visible (Android < 13). You can specify a custom default icon and a custom default color by adding these lines inside the application tag to set the custom default icon and custom color. You'll need to have already created the icon resource in your android application. Icon assets can be created by following these steps

<application>
    <!-- Set custom default icon for OkVerify's foreground service -->
    <meta-data android:name="io.okhi.android_background_geofencing.foreground_notification_icon" android:resource="@drawable/ic_person_pin" />
    <!-- Set custom default icon color for OkVerify's foreground service -->
    <meta-data android:name="io.okhi.android_background_geofencing.foreground_notification_color" android:resource="@color/colorAccent" />
    
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Starting verification without using OkHiLocationManager

If your user created an address with OkHi and you have a valid OkHi locationId, pair of coordinates and user information such as a phone number, you can start verification without using the OkHiLocationManagerResponse object

import {start} from 'react-native-okhi';

const location = {id: '<user_okhi_location_id>', lat: -1.2344, lon: 34.83872};
await start('+234xxxx', location.id, location.lat, location.lon);

Building with pro-guard enabled

If you have minifyEnabled set to true in your build.gradle file located android/app/build.gradle, you'll need to modify your proguard-rules.pro file, located android/app/proguard-rules.proas shown bellow to include classes required by the library to run.

-dontwarn sun.reflect.**
-dontwarn java.beans.**
-dontwarn sun.nio.ch.**
-dontwarn sun.misc.**

-keep class com.esotericsoftware.** {*;}

-keep class java.beans.** { *; }
-keep class sun.reflect.** { *; }
-keep class sun.nio.ch.** { *; }

-keep class com.snappydb.** { *; }
-dontwarn com.snappydb.**

# If you don't use OkHttp as a dep and the following

-dontwarn org.codehaus.mojo.animal_sniffer.*
-dontwarn javax.annotation.**
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
-dontwarn org.codehaus.mojo.animal_sniffer.*
-dontwarn okhttp3.internal.platform.ConscryptPlatform
-dontwarn org.conscrypt.ConscryptHostnameVerifier

Prepare for submission to Google Play store and App Store

Submitting an app to Google Play store and App Store that has background location permissions has a few extra requirements. Follow these guide to know what to expect and how to handle the extra requirements:

Publishing to Google Play store

Publishing to App Store

Create home or work addresses

You may turn off either of the OkHi address types. This is to allow your users to create either home or work addresses to better suit your use-case. By default both address types are on.

<OkHiLocationManager
  ...// normal configuration
  config={{ addressTypes: { home: true, work: false } }}
/>

Managing verification start requirements

For Addresses to be verified, the following requirements must be satisfied.

  1. User grants background location permission for digital verification or when in use location permission for physical verification on both Android / iOS

  2. Location services must be turned on both Android / iOS

  3. Google Play Services must be available on Android

Luckily the OkHi library has helper methods to assist you with these requirements.

The request function will go ahead and requests for background location permission as well as activate any services that might be offline. If you'd like a much fine grain control over how permissions are requested please see the API reference.

Make sure to go over our best practices doc requirement to make sure your application meets Play Store and App Store guidelines for requesting for background location permission.

Leveraging OkVerify's Android foreground service

OkVerify's foreground service improves the reliability and stability of verification signals coming from your user's Android device. Here's how to use it

Due to the Background Execution Limits introduced in Android 8 as well as restrictions imposed by some device manufacturers its become increasingly difficult to determine accurate and timely verification signals within android applications. In order to ensure reliability of these verification signals, the library comes with an opt-in foreground service that you can leverage to decrease the amount of time it takes to verify an address.

Starting the foreground service

Configure a notification that'll be used to start the service. If you followed the previous guide, this should already be setup.

The foreground service is started by default once verification of an address starts, but can also be started again if previously stopped using the startForegroundService function

import { startForegroundService } from '@okhi/react-native-okverify';
 
const startedForegroundService = await startForegroundService(); // returns true || false indicating success of the process 

Stopping the foreground service

Stopping the service is easy, simply make a call to the stopForegroundService function

import { stopForegroundService } from '@okhi/react-native-okverify'
// stops the running foreground service
const stoppedForeground = await stopForegroundService();

Stopping the foreground service does not stop verification of that address, the library will continue to use background services in order to obtain verification signals.

Determining whether the foreground service is running

You can make a call to the isForegroundServiceRunning function to determine whether a foreground service is present and running

import { isForegroundServiceRunning } from '@okhi/react-native-okverify'
// stops the running foreground service
const serviceRunning = await isForegroundServiceRunning();

Next steps

Review Full integration sample project

Review OkHi integration best practices

Last updated