react-native-spike-sdk
TypeScript icon, indicating that this package has built-in type declarations

2.3.7 • Public • Published

Spike ReactNative SDK is a library on top of Apple HealthKit and Android HealthConnect that

  1. Helps with the extraction of data.

  2. Pushes data to SpikeAPI and delivers standardized data.

Table of contents

Requirements

  • iOS 13.0+

  • Android 9.0+

🚨 Expo: This package is not available in the Expo Go app. Learn how you can use it with custom dev clients.

Installation

Install the react-native-spike-sdk package from npm

yarn add react-native-spike-sdk

npm install react-native-spike-sdk

Use pod install and pod update commands from ios/ folder of your app to install/update pods afterward.

iOS Setup

iOS Signing & Capabilities

To add HealthKit support to your application's Capabilities.

  • Open the ios/ folder of your project in Xcode

  • Select the project name in the left sidebar

  • Open Signing & Capabilities section

  • In the main view select + Capability and double click HealthKit

  • Allow Clinical Health Records and Background Delivery if needed.

More details you can find here.

Info.plist

Add Health Kit permissions descriptions to your Info.plist file.

<key>NSHealthShareUsageDescription</key>
<string>We will use your health information to better track workouts.</string>

<key>NSHealthUpdateUsageDescription</key>
<string>We will update your health information to better track workouts.</string>

<key>NSHealthClinicalHealthRecordsShareUsageDescription</key>
<string>We will use your health information to better track  workouts.</string>

Android Setup

First of all you have to add the required health permissions to your "AndroidManifest.xml" file

<uses-permission android:name="android.permission.health.READ_SLEEP"/>
<uses-permission android:name="android.permission.health.READ_WEIGHT"/>
<uses-permission android:name="android.permission.health.READ_ACTIVE_CALORIES_BURNED"/>
<uses-permission android:name="android.permission.health.READ_BASAL_METABOLIC_RATE"/>
<uses-permission android:name="android.permission.health.READ_BLOOD_GLUCOSE"/>
<uses-permission android:name="android.permission.health.READ_BLOOD_PRESSURE"/>
<uses-permission android:name="android.permission.health.READ_BODY_FAT"/>
<uses-permission android:name="android.permission.health.READ_BONE_MASS"/>
<uses-permission android:name="android.permission.health.READ_EXERCISE"/>
<uses-permission android:name="android.permission.health.READ_DISTANCE"/>
<uses-permission android:name="android.permission.health.READ_ELEVATION_GAINED"/>
<uses-permission android:name="android.permission.health.READ_FLOORS_CLIMBED"/>
<uses-permission android:name="android.permission.health.READ_HEART_RATE"/>
<uses-permission android:name="android.permission.health.READ_HEART_RATE_VARIABILITY"/>
<uses-permission android:name="android.permission.health.READ_HEIGHT"/>
<uses-permission android:name="android.permission.health.READ_OXYGEN_SATURATION"/>
<uses-permission android:name="android.permission.health.READ_POWER"/>
<uses-permission android:name="android.permission.health.READ_RESPIRATORY_RATE"/>
<uses-permission android:name="android.permission.health.READ_RESTING_HEART_RATE"/>
<uses-permission android:name="android.permission.health.READ_SPEED"/>
<uses-permission android:name="android.permission.health.READ_STEPS"/>
<uses-permission android:name="android.permission.health.READ_TOTAL_CALORIES_BURNED"/>
<uses-permission android:name="android.permission.health.READ_BODY_TEMPERATURE"/>
<uses-permission android:name="android.permission.health.READ_BASAL_METABOLIC_RATE" />
  1. Also add the following query in the node:
<queries>
    <package android:name="com.google.android.apps.healthdata" />
</queries>
  1. As well as that you have to add intent filter to your activity definition so that you can request the permissions at runtime. This intent filter reference should be added under the node, mostly in the .
<intent-filter>
    <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
</intent-filter>

*For Android 14 support you also need to add additional intent-filters:

<intent-filter>
  <action
          android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
  <category
          android:name="android.intent.category.HEALTH_PERMISSIONS"/>
</intent-filter>
  1. For Android 14 support additional manifest element inside application tag
<activity-alias
        android:name="ViewPermissionUsageActivity"
        android:exported="true"
        android:targetActivity=".MainActivity"
        android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
  <intent-filter>
    <action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
    <category android:name="android.intent.category.HEALTH_PERMISSIONS" />
  </intent-filter>
</activity-alias>
  1. In case permissions handling is not working, this might be related to launch mode being singleTop. This might be not needed, but some apps faced problems when requesting permissions. If you face them, then you should try removing the following line:
android:launchMode="singleTop"
  1. In case app is not building, it might be related to label replacement issue. In this case, you should add the following line to the tag:
tools:replace="android:label"
  1. Since we are using closed source native Android SDK, separate repository is needed. Thus, add the following dependency into your android/builde.gradle file (it must be added both in repositories and allprojects node of repositories):
maven {
  url 'https://gitlab.com/api/v4/projects/43396247/packages/maven'
}

Check HealthConnect availability (Android Only)

Check if Health Connect installed on a device.

const isPackageInstalled = await Spike.isPackageInstalled();

Check HealthStore data availability (iOS Only)

Check if Health Store data available on a device.

const isAvailable = await Spike.isHealthDataAvailable();

Spike SDK usage

Start getting Spike data in 3 steps. All Spike SDK async method calls should be wrapped into try catch block.

1. Create Spike connection

To set up the Spike SDK create SpikeConnection instance with SpikeConnectionConfig object. From the 2.1.x version Spike SDK automatically manages connection persistance and restore connection if finds one with same appId, authToken and customerEndUserId. With each new connection creating call callbackUrl and env could be overridden. Provide SpikeLogger implementation to handle connection logs.

import Spike from 'react-native-spike-sdk';

const conn = await Spike.createConnection(
  {
    appId: 'my_app_id',
    authToken: 'my_app_access_token',
    customerEndUserId: 'my_user_id',
    callbackUrl: 'my_callback_url', // Optional, provides functionality to send data to webhook and use background deliveries.
    env: 'PROD', // Optional, default value PROD.
  },
  logger // Optional, class which conforms to SpikeLogger interface
);

2. Permissions

Provide permissions to access iOS HealthKit and Android HealthConnect data. Spike SDK methods will check required permissions and request them if needed. Permission dialog may not be shown according on platform permissions rules.

// conn was created in the previous step

if (Platform.OS === 'android') {
  // Android methods should be called on connection instance
  const isGranted = await conn.checkPermissionsGranted(
    SpikeDataTypes.activitiesStream
  );
  if (!isGranted) {
    await conn.requestHealthPermissions(SpikeDataTypes.activitiesStream);
  }

  // Or request multiple permissions
  await conn.requestHealthPermissions([
    SpikeDataTypes.activitiesStream,
    SpikeDataTypes.steps,
  ]);
}

if (Platform.OS === 'ios') {
  // iOS method should be called on Spike class
  await Spike.ensurePermissionsAreGranted([
    SpikeDataTypes.activitiesStream,
    SpikeDataTypes.steps,
  ]); // Provide required Spike data types
}

3. Extract data

There are two ways to get Spike data: to your webhook or directly in your app. Extract data methods requires SpikeExtractConfig object, where date range can be provided optionally. By providing range greater than one day samples array of result object will be empty. The maximum permitted date range for iOS is 90 days, while for Android it's 30 days.

Extract data locally

According to the provided SpikeDataType result object may be different.

// conn was created in the previous step

// Extract steps data for today
const data = await conn.extractData({
  dataType: SpikeDataTypes.steps,
});

// OR you can provide same day
const today = new Date() // could be any day
const data = await conn.extractData({
    SpikeDataTypes.steps,
    from: today,
    to: today
});
// conn was created in the previous step

// Extract steps data for yesterday and today.
const today = new Date();
const yesterday = new Date();
yesterday.setDate(today.getDate() - 1);
const data = await conn.extractData({
  dataType: SpikeDataTypes.steps,
  from: yesterday,
  to: today,
});

Extract data to webhook

Ensure callbackUrl was provided to SpikeConnection, otherwise you will get SpikeCallbackURLNotProvidedException error. Method will return job information object.

// conn was created in the previous step

// Send today's steps data to webhook
const data = await conn.extractAndPostData({
  dataType: SpikeDataTypes.steps,
});

// OR you can provide same day
const today = new Date(); // could be any day
const data = await conn.extractAndPostData({
  dataType: SpikeDataTypes.steps,
  from: today,
  to: today,
});
// conn was created in the previous step

// Send yesterday's and today's steps data to webhook
const today = new Date();
const yesterday = new Date();
yesterday.setDate(today.getDate() - 1);
const data = await conn.extractAndPostData({
  dataType: SpikeDataTypes.steps,
  from: yesterday,
  to: today,
});

Background deliveries (iOS Only)

Background delivery enables asynchronous data delivery to the customer backend by means of webhooks. It enables data updates to be sent to the backend even when the application is hidden or closed. Background delivery is only supported on iOS devices at the moment. Background deliveries will send whole day data to the webhook.

Configure for background deliveries

Under your project Signing & Capabilities section enable Background Delivery for HealthKit. Call Spike configure methods on each app start to trigger background deliveries tasks. Add Spike initialization code to ios/<Project Name>/AppDelegate.mm file inside application:didFinishLaunchingWithOptions: method.

If you plan on supporting background delivery, you need to set up all observer queries in your app delegate. Spike SDK will do it by calling configure() method. Read more Receive Background Updates.

import <SpikeSDK/SpikeSDK-Swift.h>
...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  ...
  [Spike configure];
  ...

}

Register connection for background deliveries

Ensure callbackUrl was provided to SpikeConnection, otherwise you will get SpikeCallbackURLNotProvidedException error. Provide required Spike Data types to enableBackgroundDelivery method, it could be called after connection is created.

await conn.enableBackgroundDelivery([
  SpikeDataTypes.activitiesSummary,
  SpikeDataTypes.steps,
]);
  • If dataTypes is not empty, then a daemon task is started which will listen for data updates coming from the platform and send them via webhooks in the background; the operation is not compound and each method call will override enabled background data types list;

  • If dataTypes parameter is empty or null, then background data delivery is stopped for this connection if it was enabled;

You can check if connection have active background deliveries listeners. If background delivery is not enabled, an empty set is returned.

const dataTypes = await conn.getBackgroundDeliveryDataTypes();

Logging

Internally, the React Native SDK supports logging on various levels to assist with troubleshooting. However, to avoid imposing additional third-party dependencies on library users, the SDK expects a concrete logging implementation to be provided externally. This can be done by implementing the SpikeLogger class and providing it when creating a connection.

Below is an example of how to implement a simple console logger.

class ConsoleLogger implements SpikeLogger {
  isDebugEnabled() {
    return true;
  }

  isInfoEnabled() {
    return true;
  }

  isErrorEnabled() {
    return true;
  }

  debug(connection: SpikeConnection, message: string) {
    console.log(`[SPIKE_DEBUG] ${message}`);
  }

  info(connection: SpikeConnection, message: string) {
    console.log(`[SPIKE_INFO] ${message}`);
  }

  error(connection: SpikeConnection, message: string) {
    console.log(`[SPIKE_ERROR] ${message}`);
  }
}

Spike SDK provides background delivery process logs. This can be done by implementing the SpikeBackgroundDeliveriesLogger class and providing it though connection's setListener method.

Below is an example of how to implement a simple console logger.

class BackgroundDeliveriesLogger implements SpikeBackgroundDeliveriesLogger {
  onBackgroundLog(log: string) {
    console.log(`[BACKGROUND_LOG] ${log}`);
  }
}

Spike Data types

  • SpikeDataTypes.activitiesStream
  • SpikeDataTypes.activitiesSummary
  • SpikeDataTypes.body
  • SpikeDataTypes.breathing
  • SpikeDataTypes.calories
  • SpikeDataTypes.distance
  • SpikeDataTypes.glucose
  • SpikeDataTypes.heart
  • SpikeDataTypes.info
  • SpikeDataTypes.oxygenSaturation
  • SpikeDataTypes.sleep
  • SpikeDataTypes.steps

Classes

Spike

Class Method Description iOS Android
Spike createConnection Creates a new SpikeConnection instance with the given user details.
Parameters: config (SpikeConnectionConfig), logger? (SpikeLogger) .
Returns: An instance of the SpikeConnection class (SpikeConnection).
yes yes
Spike getBackgroundConnections Returns all connections that are configured to deliver data in the background.
Returns: An array of SpikeConnection instances with callbackUrl (Array<SpikeConnection>).
yes yes
Spike ensurePermissionsAreGranted Verifies that platform-specific permissions corresponding to the Spike data types provided are granted. In the event that some permissions are not granted, a platform-specific permissions dialogue will be presented to the end-user. This method should only be invoked from a UI component.
Parameters: permissions (Array<SpikeDataType>)
yes no
Spike isPackageInstalled Check if Health Connect installed on a device.
Returns: isInstalled (Bool)
no yes
Spike isHealthDataAvailable Check if Health Store data available on the device.
Returns: isAvailable (Bool)
yes no

SpikeConnection

Class Method Description iOS Android
SpikeConnection getAppId Retrieves the unique Spike application identifier.
Returns: appId (string)
yes yes
SpikeConnection getSpikeEndUserId Retrieves the unique identifier assigned to the end-user by Spike.
Returns: spikeEndUserId (string)
yes yes
SpikeConnection getCustomerEndUserId Retrieves the unique identifier assigned to the end-user by the customer.
Returns: customerEndUserId (string)
yes yes
SpikeConnection getCallbackUrl Returns the URL that will receive webhook notifications.
Returns: callbackUrl (string)
yes yes
SpikeConnection close Terminates any ongoing connections with Spike’s backend servers, clears any caches, and removes provided user details and tokens from the memory. Once the connection is closed, it cannot be used, and any method other than close() will throw a SpikeConnectionIsClosedException exception. yes yes
SpikeConnection extractData Extracts local device data for the current date in the end-user’s time zone. Optionally time range can be provided.
*On iOS, the maximum allowed single-query time interval is 90 days. If required, data of any longer time period can be accessed by iterating multiple queries of 90 days.
*On Android the earliest date data can be requested for is 30 days before a permission was given to the user's app to read from HealthConnect. There is no limit on how many days in total.
Parameters: config (SpikeExtractConfig)
Returns: An instance of SpikeData. The concrete type will depend on the data type requested
yes yes
SpikeConnection extractAndPostData Extracts local device data for the current date in the local user time zone and sends it as a webhook notification to the customer’s backend. Optionally time range can be provided.
*On iOS, the maximum allowed single-query time interval is 90 days. If required, data of any longer time period can be accessed by iterating multiple queries of 90 days.
*On Android the earliest date data can be requested for is 30 days before a permission was given to the user's app to read from HealthConnect. There is no limit on how many days in total.
Parameters: config (SpikeExtractConfig)
yes yes
SpikeConnection setListener Sets a listener that is to handle notifications from the background delivery process.
Parameters: listener (SpikeBackgroundDeliveriesLogger)
*If listener is not null, then any existing listener is replaced
yes no
SpikeConnection manageHealthConnect Opens your device's HealthConnect menu, where you can switch on and off data access for the app as well as delete data. no yes
SpikeConnection checkPermissionsGranted Initiates a check on whether health permissions have been granted for specified data type.
Parameters: dataType (SpikeDataType)
Returns: permissions are granted (boolean)
no yes
SpikeConnection getHealthConnectAvailability Provides information on whether HealthConnect is available on the device. no yes
SpikeConnection revokeAllPermissions Revokes all granted health permissions for the application. no yes
SpikeConnection requestHealthPermissions Requests all the supported health read permissions for provided data types from HealthConnect.
Parameters: dataTypes (SpikeDataType or Array<SpikeDataType>)
no yes

SpikeLogger

Abstract class allowing to receive notifications from the SDK's processes.

Class Method Description iOS Android
SpikeLogger isDebugEnabled Manages is Debug level logging enabled.
Returns: are Debug level logs enabled (boolean)
yes yes
SpikeLogger isInfoEnabled Manages is Info level logging enabled.
Returns: are Info level logs enabled (boolean)
yes yes
SpikeLogger isErrorEnabled Manages is Error level logging enabled.
Returns: are Error level logs enabled (boolean)
yes yes
SpikeLogger debug Invoked on Spike SKD Debug log events.
Parameters: connection (SpikeConnection), message (string)
yes yes
SpikeLogger info Invoked on Spike SKD Info log events.
Parameters: connection (SpikeConnection), message (string)
yes yes
SpikeLogger error Invoked on Spike SKD Error log events.
Parameters: connection (SpikeConnection), message (string)
yes yes

SpikeBackgroundDeliveriesLogger

Abstract class allowing to receive notifications from the background data delivery process.

Class Method Description iOS Android
SpikeBackgroundDeliveriesLogger onBackgroundLog Invoked on background deliveries events.
Parameters: log (string)
yes no

SpikeConnectionConfig

Type required to create Spike connection instance.

Type Property Type Description iOS Android
SpikeConnectionConfig appId string The unique Spike application identifier yes yes
SpikeConnectionConfig authToken string The unique identifier assigned to the end-user by Spike. yes yes
SpikeConnectionConfig customerEndUserId string the unique identifier assigned to the end-user by the customer. yes yes
SpikeConnectionConfig callbackUrl string URL that will receive webhook notifications yes yes
SpikeConnectionConfig env SpikeEnvironment Spike environment yes yes

SpikeExtractConfig

Type required to extract data.

Type Property Type Description iOS Android
SpikeExtractConfig dataType SpikeDataType The Spike data type to make extraction for. yes yes
SpikeExtractConfig from Date (optional) Extraction time range start date.
*Required if to property passed.
yes yes
SpikeExtractConfig to Date (optional) Extraction time range end date.
*Required if from property passed.
yes yes

SpikeEnvironment

Type required to set Spike connection environment.

'PROD' - Production environment

'DEV' - Test environment

Data types

The following table shows the data types that can be read from HealthConnect API and the permissions that are required to read them.

Spike Data Type HealthConnect permission
SpikeDataTypes.HEART_RATE android.permission.health.READ_HEART_RATE
android.permission.health.READ_HEART_RATE_VARIABILITY
android.permission.health.READ_RESTING_HEART_RATE
SpikeDataTypes.DISTANCE android.permission.health.READ_DISTANCE
SpikeDataTypes.ACTIVITIES_STREAM android.permission.health.READ_EXERCISE
android.permission.health.READ_STEPS
android.permission.health.READ_DISTANCE
android.permission.health.READ_TOTAL_CALORIES_BURNED
android.permission.health.READ_HEART_RATE
android.permission.health.READ_SPEED
android.permission.health.READ_ELEVATION_GAINED
android.permission.health.READ_POWER
android.permission.health.READ_HEART_RATE_VARIABILITY
SpikeDataTypes.ACTIVITIES_SUMMARY android.permission.health.READ_STEPS
android.permission.health.READ_ACTIVE_CALORIES_BURNED
android.permission.health.READ_TOTAL_CALORIES_BURNED
android.permission.health.READ_DISTANCE
android.permission.health.READ_ELEVATION_GAINED
android.permission.health.READ_FLOORS_CLIMBED
android.permission.health.READ_HEART_RATE
android.permission.health.READ_RESTING_HEART_RATE
android.permission.health.READ_BASAL_METABOLIC_RATE
SpikeDataTypes.BREATHING android.permission.health.READ_RESPIRATORY_RATE
SpikeDataTypes.CALORIES android.permission.health.READ_TOTAL_CALORIES_BURNED
android.permission.health.READ_ACTIVE_CALORIES_BURNED
SpikeDataTypes.GLUCOSE android.permission.health.READ_BLOOD_GLUCOSE
SpikeDataTypes.OXYGEN_SATURATION android.permission.health.READ_OXYGEN_SATURATION
SpikeDataTypes.SLEEP android.permission.health.READ_SLEEP
android.permission.health.READ_HEART_RATE
android.permission.health.READ_HEART_RATE_VARIABILITY
SpikeDataTypes.STEPS android.permission.health.READ_STEPS
SpikeDataTypes.BODY android.permission.health.READ_WEIGHT
android.permission.health.READ_HEIGHT
android.permission.health.READ_BODY_FAT
android.permission.health.READ_BONE_MASS
android.permission.health.READ_BLOOD_PRESSURE
android.permission.health.READ_BODY_TEMPERATURE

Errors and Exceptions

SpikeException

The abstract parent of all concrete exceptions.

SpikeConnectionIsClosedException

Thrown if any method is invoked on SpikeConnection or one of its subclasses after the connection has been closed.

SpikeInvalidCredentialsException

Thrown if the credentials provided are not recognised, i.e. are invalid or expired.

SpikeInvalidDateRangeException

Thrown if duration exceeds the allowed maximum or if ‘from’ date is greater than ‘to’ date. The message will contain a specific cause description.

SpikeInvalidCallbackUrlException

Thrown if the callback URL is not a valid URL, does not have HTTPS schema, or is not a sub-URL of the main callback URL configured for the application. The exception message will contain a specific reason.

SpikePermissionsNotGrantedException

Thrown when Spike SDK is unable to access the data due to permissions not being granted.

SpikeServerException

Whenever any operation with the Spike backend fails and the error does not fall into any of the above exceptions. The exception cause will contain the underlying error.

SpikeCallbackURLNotProvidedException

Thrown when a method which requires callback url is called, but callback url is not set for current connection.

Package Sidebar

Install

npm i react-native-spike-sdk

Weekly Downloads

154

Version

2.3.7

License

MIT

Unpacked Size

324 kB

Total Files

200

Last publish

Collaborators

  • anton.autushka
  • ekroman
  • spikeapiadmin