Skip to main content

React Native SDK Usage & Integration

Learn how to initialize the DoorstepAI SDK and integrate delivery tracking into your React Native application.

SDK Initialization

Basic Setup with RootDoorstepAI Component

The easiest way to initialize the SDK is using the RootDoorstepAI component, which handles initialization and permission requests automatically. RootDoorstepAI is optional as of the latest SDK release; data collection begins when you call startDelivery* as long as you initialize the SDK and set the API key elsewhere.

App.js
import React from 'react';
import { View, StyleSheet } from 'react-native';
import { DoorstepAI, RootDoorstepAI } from '@doorstepai/dropoff-sdk';

export default function App() {
return (
<View style={styles.container}>
<RootDoorstepAI
apiKey="your_api_key_here"
notificationTitle="Tracking..."
notificationText="Tracking your delivery"
/>
{/* Your app content */}
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
},
});

Core Functionality

Delivery IDs

Delivery IDs are designed to be unique identifiers for each delivery session. Use meaningful, unique identifiers that help you track and manage your deliveries effectively.

Starting Delivery Tracking

The SDK provides multiple methods to start delivery tracking based on different address formats.

Every start method accepts these optional knobs (passed via a trailing options object):

  • timeoutSeconds — auto-stops tracking after the given duration, as a backstop in case an exit geofence is missed.
  • autoStopAfterDropoffSeconds — auto-stops tracking the given number of seconds after markDropoff is called. If omitted, the SDK falls back to the value in remote config.
  • manualForeground (Android only) — when true, the SDK does not promote its tracking service to the foreground; the host app must already be running its own foreground service.

The address/addressString variants additionally accept coordinates: { lat, lng } so you can pair a textual address with the lat/lng you already resolved upstream.

1. Start by Place ID

import { DoorstepAI } from '@doorstepai/dropoff-sdk';

const startDeliveryByPlaceID = async () => {
try {
const result = await DoorstepAI.startDeliveryByPlaceID(
'some_place_id',
'delivery_12345',
{
timeoutSeconds: 1200, // optional
autoStopAfterDropoffSeconds: 600, // optional
manualForeground: false, // optional, Android-only
}
);
console.log('✅ Delivery started successfully:', result);
// Handle successful start
} catch (error) {
console.error('❌ Failed to start delivery:', error);
// Handle error
}
};
Geofence Start Requirement

Execute startDelivery... when the driver enters the delivery geofence around the target building. Do not start inside the building.

2. Start by Address Components

const startDeliveryByAddress = async () => {
const address = {
streetNumber: '123',
route: 'Main Street',
subPremise: 'Apt 4B',
locality: 'San Francisco',
administrativeAreaLevel1: 'CA',
postalCode: '94102',
};

try {
const result = await DoorstepAI.startDeliveryByAddress(
address,
'delivery_12345',
{
coordinates: { lat: 37.7749, lng: -122.4194 }, // optional
timeoutSeconds: 1200, // optional
autoStopAfterDropoffSeconds: 600, // optional
manualForeground: false, // optional, Android-only
}
);
console.log('✅ Address delivery started:', result);
} catch (error) {
console.error('❌ Address delivery failed:', error);
}
};

3. Start by Address String

const startDeliveryByAddressString = async () => {
try {
const result = await DoorstepAI.startDeliveryByAddressString(
'123 Main St, Apt 4B, San Francisco, CA 94102',
'delivery_12345',
{
coordinates: { lat: 37.7749, lng: -122.4194 }, // optional
timeoutSeconds: 1200, // optional
autoStopAfterDropoffSeconds: 600, // optional
manualForeground: false, // optional, Android-only
}
);
console.log('✅ Address string delivery started:', result);
} catch (error) {
console.error('❌ Address string delivery failed:', error);
}
};

Deprecated: Start by Plus Code

Deprecated

startDeliveryByPlusCode is deprecated. Use startDeliveryByAddressString (or startDeliveryByAddress) and pass coordinates if you have them.

// Deprecated — kept for backwards compatibility.
await DoorstepAI.startDeliveryByPlusCode('some_plus_code', 'delivery_12345', 1200);

Deprecated: Start by Lat/Lng

Deprecated

startDeliveryByLatLng is deprecated. Use startDeliveryByAddressString or startDeliveryByAddress with the coordinates parameter instead.

// Deprecated — kept for backwards compatibility.
await DoorstepAI.startDeliveryByLatLng(37.7749, -122.4194, 'Apt 4B', 'delivery_12345', 1200);
  • Use both an enter and exit geofence to bound the delivery session.
  • A radius of 250m or larger typically yields the best results.

Delivery Events

Track important delivery milestones using event reporting:

Mark Dropoff (POD or non-POD)

const markDropoff = async () => {
try {
await DoorstepAI.markDropoff(
'delivery_12345',
'pod' // or 'non_pod'
);
console.log('✅ Dropoff marked');
} catch (error) {
console.log('❌ Dropoff mark failed: ' + (error?.message ?? String(error)));
}
};
// NOTE: The previous methods of marking a dropoff still work as expected.
const reportCustomEvent = async () => {
try {
await DoorstepAI.newEvent(
'taking_pod',
'delivery_12345'
);
console.log('Event sent');
} catch (error) {
console.log('Event send failed: ' + (error?.message ?? String(error)));
}
};

Stopping Delivery Tracking

Stop tracking when the delivery is complete:

const stopDelivery = async () => {
try {
await DoorstepAI.stopDelivery('delivery_12345');
console.log('🛑 Delivery tracking stopped');
} catch (error) {
console.error('❌ Error stopping delivery:', error);
}
};
Geofence Stop Requirement

Execute stopDelivery(...) when the driver exits the delivery geofence surrounding the building. Do not stop inside the building.

Address Types Reference

AddressType Interface

type AddressType = {
streetNumber: string;
route: string;
subPremise: string;
locality: string;
administrativeAreaLevel1: string;
postalCode: string;
};

LatLngObject

Pair a textual address with lat/lng you already resolved upstream by passing it as coordinates on startDeliveryByAddress or startDeliveryByAddressString.

type LatLngObject = {
lat: number;
lng: number;
};

Start Options

type StartDeliveryOptions = {
coordinates?: LatLngObject; // address-string + address-components only
timeoutSeconds?: number;
autoStopAfterDropoffSeconds?: number;
manualForeground?: boolean; // Android only — no-op on iOS
};

Usage Examples

// Minimal address
const simpleAddress = {
streetNumber: '456',
route: 'Oak Avenue',
subPremise: '',
locality: 'Oakland',
administrativeAreaLevel1: 'CA',
postalCode: '94610'
};

// Complete address with apartment
const detailedAddress = {
streetNumber: '789',
route: 'Pine Street',
subPremise: 'Suite 100',
locality: 'Berkeley',
administrativeAreaLevel1: 'California',
postalCode: '94704'
};

Advanced APIs

Requesting Permissions Up-Front (iOS)

Trigger the iOS Motion/Fitness + Location permission prompts before the first delivery:

import { Platform } from 'react-native';
import { DoorstepAI } from '@doorstepai/dropoff-sdk';

if (Platform.OS === 'ios') {
// Defaults to "Always" location authorization. Pass false for when-in-use.
await DoorstepAI.requestAllPermissions(true);
}

Retrying GNSS After Permission Grants (Android)

If the user grants location permissions after SDK init, retry GNSS callback registration so raw GNSS data starts flowing:

import { Platform } from 'react-native';
import { DoorstepAI } from '@doorstepai/dropoff-sdk';

if (Platform.OS === 'android') {
await DoorstepAI.retryGnssCallbacks();
}

Remote Logging

Stream SDK logs to DoorstepAI for support investigations:

await DoorstepAI.configureRemoteLogging({
enabled: true,
minLevel: 'warning', // 'debug' | 'info' | 'warning' | 'error'
flushInterval: 30, // seconds
batchSize: 50,
maxQueueSize: 1000,
});

Dev Mode

Validate the API token and enable dev mode if it's authorized:

const enabled = await DoorstepAI.enableDevMode('YOUR_API_KEY');
if (enabled) {
console.log('✅ Dev mode active');
}

Best Practices

1. Error Handling

Always implement proper error handling for SDK methods:

const startDeliveryWithErrorHandling = async (placeID, deliveryId) => {
try {
const result = await DoorstepAI.startDeliveryByPlaceID(placeID, deliveryId);
// handle success
} catch (error) {
// handle error
}
};

2. Lifecycle Management

Handle app lifecycle changes appropriately:

import React, { useEffect } from 'react';
import { AppState } from 'react-native';

const DeliveryManager = () => {
useEffect(() => {
const handleAppStateChange = (nextAppState) => {
if (nextAppState === 'background') {
// SDK automatically handles background processing
console.log('📱 App entered background - SDK continues tracking');
} else if (nextAppState === 'active') {
console.log('📱 App returned to foreground');
}
};

const subscription = AppState.addEventListener('change', handleAppStateChange);
return () => subscription?.remove();
}, []);

// Your delivery management logic
};

3. Permission Handling

The RootDoorstepAI component automatically handles permission requests, but you can also handle them manually:

import { PermissionsAndroid, Platform } from 'react-native';

const requestPermissions = async () => {
if (Platform.OS === 'android') {
try {
const permissionsToRequest = [
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
PermissionsAndroid.PERMISSIONS.ACTIVITY_RECOGNITION,
];

// Add background location permission for Android 10+ (API 29+)
if (Platform.Version >= 29) {
permissionsToRequest.push(PermissionsAndroid.PERMISSIONS.ACCESS_BACKGROUND_LOCATION);
}

const granted = await PermissionsAndroid.requestMultiple(permissionsToRequest);

if (
granted[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] ===
PermissionsAndroid.RESULTS.GRANTED &&
granted[PermissionsAndroid.PERMISSIONS.ACTIVITY_RECOGNITION] ===
PermissionsAndroid.RESULTS.GRANTED
) {
console.log('✅ Required Android permissions granted');

// Check if background location was requested and granted
if (Platform.Version >= 29 &&
granted[PermissionsAndroid.PERMISSIONS.ACCESS_BACKGROUND_LOCATION] ===
PermissionsAndroid.RESULTS.GRANTED) {
console.log('✅ Background location permission granted');
}
} else {
console.warn('❌ One or more required Android permissions denied');
}
} catch (err) {
console.warn('❌ Error requesting Android permissions:', err);
}
} else if (Platform.OS === 'ios') {
console.log('📱 iOS: Ensure location and motion usage descriptions are in Info.plist');
}
};

Next Steps

Now that you have the SDK installed and configured:

  1. 📚 Learn SDK Usage - Initialize and use the SDK
  2. 💡 View Examples - See complete implementation examples