Skip to main content

React Native SDK Examples & Troubleshooting

Quickstart

The address-string method keeps timeout and coordinates as positional arguments; delivery options are the fifth argument.

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

await DoorstepAI.init('Tracking...', 'Tracking your delivery');
DoorstepAI.setApiKey('your_api_key');

const foreground = await DoorstepAI.requestPermissions([
'locationWhenInUse',
'motionFitness',
'bluetoothScan',
]);
if (foreground.statuses.locationWhenInUse?.state === 'granted') {
await DoorstepAI.requestPermissions(['locationAlways']);
}

await DoorstepAI.startDeliveryByAddressString(
'123 Main St, Apt 4B, San Francisco, CA 94102',
'delivery_12345',
1800,
{ lat: 37.7749, lng: -122.4194 },
{
customerId: 'customer_42',
driverId: 'driver_7',
},
);

await DoorstepAI.newEvent('taking_pod', 'delivery_12345');
await DoorstepAI.markDropoff('delivery_12345', 'pod');
await DoorstepAI.stopDelivery('delivery_12345');

Route-managed lifecycle

const listener = DoorstepAI.addGeofenceSessionListener((event) => {
console.log(event.deliveryId, event.type, event.reason);
});

await DoorstepAI.startRouteGeofencing(
[
{
deliveryId: 'delivery_12345',
address: '123 Main St, San Francisco, CA',
latitude: 37.7749,
longitude: -122.4194,
customerId: 'customer_42',
driverId: 'driver_7',
},
{
deliveryId: 'delivery_67890',
address: '500 Market St, San Francisco, CA',
latitude: 37.7899,
longitude: -122.4009,
radiusMeters: 200,
},
],
{
defaultRadiusMeters: 250,
timeoutSeconds: 1800,
manualForeground: false, // Android only
},
);

// Call when the driver completes the stop. A later EXIT can then stop it.
await DoorstepAI.markDropoff('delivery_12345', 'pod');

// On dispatch changes, pass the complete replacement list.
await DoorstepAI.updateRouteStops(updatedStops);

// At logout or shift end:
await DoorstepAI.stopRouteGeofencing();
listener?.remove();

Call resumeRouteGeofencingIfNeeded() after initialization and API-key setup on every launch. Background route events require Always/background location permission.

Permission-state handling

Use the wrapper's canonical buckets and detailed native states instead of branching on PermissionsAndroid strings:

const { statuses, unsupported } = await DoorstepAI.checkPermissions();

switch (statuses.locationAlways?.state) {
case 'granted':
break;
case 'whenInUseOnly':
// Explain the background need, then run the second permission phase.
await DoorstepAI.requestPermissions(['locationAlways']);
break;
case 'permanentlyDenied':
case 'restricted':
// Direct the user to the operating-system Settings screen.
break;
case 'notDeclared':
// Fix AndroidManifest.xml or Info.plist in the host build.
break;
}

console.log('Buckets unavailable on this platform:', unsupported);

The request result reports requested, alreadyDetermined, unavailable, and deferred, plus the settled statuses. On Android, locationAlways is always a separate request after foreground location. On iOS, request from a user-initiated flow rather than app launch.

See React Native Permissions for every accepted bucket name, detailed result field, Android-only helper, and the full staged flow.

Troubleshooting

SDK initialization fails

  • Confirm init completes before setApiKey and before the first start.
  • Confirm the API key is present and belongs to the expected environment.
  • Wrap each asynchronous call in try/catch and log the rejected error.

A permission is unavailable or undeclared

  • unavailable means the OS, version, or hardware does not expose that bucket. Android-only Wi-Fi and notification buckets are expected to be unavailable on iOS.
  • notDeclared means the host build is missing an Android manifest entry or iOS usage-description key. Fix the build; prompting again cannot solve it.

Background tracking or route events stop

Check statuses.locationAlways.state. whenInUseOnly is foreground authorization, not a background grant. Also verify Android's foreground service is running, or pass manualForeground: true only when the host already owns one.

Start arguments fail TypeScript checks

Do not put coordinates into StartDeliveryOptions. For startDeliveryByAddressString, the order is (address, deliveryId, timeoutSeconds?, coordinates?, options?); place/address variants have their corresponding published positional signatures.

Release checklist

  • Native manifests contain every permission your whitelist requests
  • Foreground and background permission phases are tested on both platforms
  • Manual start, event, mark, and stop calls succeed
  • Route state resumes after process relaunch
  • Listener subscriptions are removed during component teardown