Terra Docs
Dashboard
  • Docs
  • API Reference
  • Changelog
  • Get started ⚡️ Choose your integration
  • Health & Fitness API
    • Overview
    • Set up your Integrations
    • Connect a User
    • Receive data updates
    • Request Historical data
    • Write data
    • Debugging FAQ
    • Mobile-Only Sources: Apple, Samsung, Google Fit
      • iOS (Swift)
      • Android (Kotlin)
      • React Native
      • Flutter
  • Streaming API
    • Getting Started
    • Wearable -> Your app
      • iOS (Swift)
      • Android
    • Your app -> Terra
      • iOS (Swift)
      • Android
    • Terra -> Your Backend
  • Teams API
  • Biomarkers API - Upcoming
Powered by GitBook
On this page
  • Setup
  • iOS Setup - Apple Health
  • Background Delivery setup (iOS)
  • Android - Health Connect
  • Initialize the SDK
  • Connect to Apple Health/Samsung Health
  • Validate the Connection
  • Disconnecting a user
  • Historical Data retrieval
  • Writing data

Was this helpful?

  1. Health & Fitness API
  2. Mobile-Only Sources: Apple, Samsung, Google Fit

React Native

PreviousAndroid (Kotlin)NextFlutter

Last updated 1 month ago

Was this helpful?

Setup

Install the terra-react package using npm (npm install terra-react), and follow the respective guides below based on the platforms you want to access

iOS Setup - Apple Health

Using XCode, open the .xcodeproj for the app in the /ios directory of your project

Background Delivery setup (iOS)

RunsetUpBackgroundDelivery in your AppDelegate's didFinishLaunchingWithOptions function

This will ensure you get updates for the user's Apple Health data automatically sent to your destination.

Data will

  • still be sent even if your app is exited/killed completely

  • only be sent if the device is unlocked

#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <TerraiOS/TerraiOS-Swift.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.moduleName = @"AwesomeProject";
  // 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 = @{};
  [Terra setUpBackgroundDelivery];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

Android - Health Connect

Follow the instructions below within the /android directory of your project

Initialize the SDK

First, initialize the TerraManager class at the top level of the app.

Terra initialization

Terra should be initialized every time your app is opened.

This is a necessary prerequisite for other SDK functions to run as expected

To do this, run the Terra manager initialization function as below:

import React, { useEffect } from 'react';
import { View, Text } from 'react-native';
import { initTerra } from 'terra-react';

const App = () => {
  useEffect(() => {
    const initializeTerra = async () => {
      try {
        const devID = 'YOUR_DEV_ID';
        const referenceId = 'YOUR_REFERENCE_ID';
        
        const successMessage = await initTerra(devID, referenceId);
        console.log('Terra initialized successfully:', successMessage);
      } catch (error) {
        console.error('Failed to initialize Terra:', error);
      }
    };

    initializeTerra();  // Call this when the app launches
  }, []);  // Empty dependency array means it runs only once, when the component mounts

  return (
    <View>
      <Text>Welcome to the App using Terra</Text>
    </View>
  );
};

export default App;

Terra is thereafter ready to be used with other functions

Connect to Apple Health/Samsung Health

Once Terra is initialized, you can create a connection.

Run the initConnection function with Connections.APPLE or Connections.SAMSUNG to have the Apple Health or Health Connect permission screen pop up.

initConnection only needs to be run a single time.

Apple Health & Health Connect prohibit the permission popup to appear more than once for any given permission, so calling initConnection more than once will result in no action at all

The only case where it would re-appear is if:

  • you call initConnection with an expanded set of customPermissions

  • the app is deleted & reinstalled.

try {
  // Example token received from your backend
  const token = 'example_token';
  
  // Define connection type and custom permissions
  const connection = Connections.APPLE;
  const customPermissions = [];      // Leave empty to default to all permissions
  const schedulerOn = true;          // Enables background delivery
  const startIntent = null;          // always leave as null - deprecated
  
  // Initialize the connection
  const successMessage = await initConnection(
    connection,      // The type of connection (e.g., Apple Health)
    token,           // Token received from backend
    schedulerOn,     // Enables background delivery
    customPermissions, // Empty array for custom permissions
    startIntent      // No startIntent needed - deprecated
  );
  
  console.log('Connection successful!', successMessage);
} catch (error) {
  console.error('Connection failed:', error);
}

customPermissions

🚧 Webviews & HealthKit permissions screen

HealthKit implements the permissions popup as a webview

If your app is also based on a webview, you will need to interrupt your webview, call initConnection, then upon completion re-open your webview

token

Validate the Connection

function getUserId(connection: Connections): Promise<GetUserId>
  • if the connection exists, all is good! 🎉 keep vibing along

Disconnecting a user

Historical Data retrieval

You may set toWebhook to false if you wish for the callback function to return the data payload on the client side.

try {
  // Example connection type and dates
  const connection = Connections.APPLE;
  const startDate = new Date();      // Replace with actual start date
  const endDate = new Date();        // Replace with actual end date
  
  // Optionally, send data to webhook or not
  const toWebhook = false;
  // Call the getDaily function
  const dataMessage = await getDaily(connection, startDate, endDate, toWebhook);

  // Handle the response based on the structure of DataMessage
  if (dataMessage.success) {
    if (dataMessage.data) {
      console.log('Daily data:', dataMessage.data);
    } else {
      console.log('Failed to unpack data');
    }
  } else {
    console.error('Request failed with error:', dataMessage.error);
  }

} catch (error) {
  // Handle failure (network error, etc.)
  console.error('Failed to get daily data:', error);
}

Writing data

You may write data into Apple Health (Health Connect not yet supported) through one of the helper functions in the SDK

device_data must be passed in for postActivity to succeed.

Internal implementation

// Create a payload for the activity data
const activityPayload: TerraActivityPayload = {
  metadata: {
    name: 'Morning Run',
    start_time: '2024-11-01T07:30:00+00:00',
    end_time: '2024-11-01T08:30:00+00:00',
    type: ActivityType.RUNNING,
  },
  device_data: {
    name:  'Terra'
  },
  heart_rate_data: {
    summary: {
      avg_hr_bpm: 130,
      max_hr_bpm: 160,
    },
  },
  distance_data: {
    summary: {
      distance_meters: 5000,
    },
  },
  calories_data: {
    total_burned_calories: 400,
  },
};

// Post the activity data
postActivity(Connections.APPLE, activityPayload)
  .then((response) => {
    if (response.success) {
      console.log('Activity data posted successfully!');
    } else {
      console.error('Failed to post activity data:', response.error);
    }
  })
  .catch((error) => {
    console.error('Error posting activity data:', error);
  });  

customPermissions is used to customize the permissions list shown in the Apple Health/Health Connect popup when calling . When empty, it defaults to all available permissions

To ensure a connection is still valid on the client side, use the method. This function is synchronous and returns the user_id right away or null if none exists.

Always use this method right after to see if the connection still exists,

if you expect the connection to exist, but returns null, to re-establish it. No permission screen will be shown again and the user flow will be unaffected

if it is expected for the connection to no longer exist, you may allow the user to re-connect Apple Health if they so choose by clicking on a "connect apple Health" button or equivalent (you'd then call , but no permission screen would be shown)

In order to disconnect an Apple Health user, you may use, called from your backend

You can request for historical data using one of the

Check out the for details about all the functions in the SDK

postActivity uses the class internally, which has been deprecated as of iOS 17.

HKWorkout
initializing Terra
call initConnection
as before

SDK Installation

Requirements

  • Android 28 and above

Inside the dependencies section of your build.gradle file, add the following line of code

implementation 'co.tryterra:terra-android:{VERSION_NUMBER}'

Sync your project with Gradle by clicking on the "Sync Project with Gradle Files" button in the toolbar. This will download the TerraAndroid SDK and make it available to your project.

Health Connect Setup

In the Health Connect app:

Give all permissions between the app you wish to read from (e.g. Samsung Health/Google Fit & Health Connect.

In your AndroidManifest.xml

Include the following tags under the Activity you wish to link the user to when they click the privacy policy link in the Health Connect permission screen:

<intent-filter>
    <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
</intent-filter>
<intent-filter>
  <action android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
  <category android:name="android.intent.category.HEALTH_PERMISSIONS"/>
</intent-filter>

Apply for Health Connect access

For each permission which you are not using, please add the following lines to your AndroidManifest.xml

<uses-permission android:name="android.permission.health.READ_HEART_RATE" tools:node="remove"/>

with android.permission.health.XXX for each permission you aren't using

installed on users' devices

You can find the latest version number on .

Before going LIVE (release), you will need to apply for permissions to access the Health Connect API with Google. Use this .

Health Connect
Maven Central
application form
initConnection
getUserId
getUserId
initConnection
the same endpoint as for Web API-based integrations
data retrieval functions.
React Native SDK reference
postActivity

If you do not need to access the , there is no reason to use Terra mobile SDKs!

If you need to access Terra's Health & Fitness API, it is only secure to do so from your server backend and send the desired data to your mobile frontend.

Never expose your API key on the client side unless you are simply testing

token is a single-use token created to ensure the authentication endpoint for creating a (and connecting the SDK to Terra's servers) does not get abused.

In order to generate it, place the call below on your server, and provide it to your client side using your own logic.

Testing & developing

During the development phase, it it acceptable to place this call on the client side, exposing your API key in your mobile app.

For a production implementation, DO NOT expose your API key this way, and make sure to only make this call from your backend

Generates an authentication token for the Terra mobile SDKs

post

Creates a token to be used with initConnection() functions in the Terra mobile SDKs in order to create a user record for Apple Health or Samsung Health (or equivalent)

Header parameters
dev-idstringRequired

your developer ID

Example: testingTerra
x-api-keystringRequired

your API key

Example: OtHJok60oQmT8zhnUWc4SWBJI7ztPTs88C0gOsJJ
Responses
200
200
application/json
404
404
application/json
post
POST /v2/auth/generateAuthToken HTTP/1.1
Host: api.tryterra.co
dev-id: text
x-api-key: text
Accept: */*
{
    "status": "success",
    "token": "250c68b9c21b78e40e7a3285a2d538d3bc24aabd3b4c76a782fb0a571ca4501d",
    "expires_in": 180
}

Summary:

  1. Add https://github.com/tryterra/TerraiOS as a package dependency

  2. Add Capabilities:

    1. Healthkit > Healthkit Background Delivery

    2. Background Modes > Background processing

    3. Background modes > Background fetch

  3. In your info.plist, add:

    1. Privacy - Health Share Usage Description: custom text shown in the Apple Health permission screen

    2. Permitted background task scheduler: co.tryterra.data.post.request

mobile-only integrations