npm package: @flowpush/app-sdk
Description: FlowPush React Native / Expo SDK.
Latest version: 1.0.0

# @flowpush/app-sdk

FlowPush React Native / Expo SDK.

This package provides a mobile-friendly client for:

- Device registration
- User identification
- Device deactivation

It is designed for Expo apps and works with the current FlowPush SDK API surface.

## Current Compatibility State

The SDK is compatible with React Native Expo apps and the current FlowPush backend mobile registration contract.

What works now:

- Register mobile devices through `POST /api/v1/sdk/mobile/devices`
- Link devices to users with `identify`
- Deactivate devices with `unregister`
- Backend native dispatch support is available for APNs/FCM/HMS providers (with app credentials configured on the backend)

## Install

```bash
pnpm add @flowpush/app-sdk
```

## Quick Start (Expo)

```ts
import * as SecureStore from "expo-secure-store"
import { FlowPushExpo } from "@flowpush/app-sdk"

const sdk = new FlowPushExpo({
  appKey: "your-flowpush-app-key",
  apiUrl: "https://your-api-host/api/v1",
})

await sdk.requestPermissionAsync()

await sdk.registerDeviceAsync({
  deviceType: "ios", // optional; SDK auto-detects when possible
  provider: "apns",
})

await sdk.identifyAsync({
  userId: "user_123",
  attributes: { plan: "pro" },
})
```

## API

### new FlowPushExpo(options)

Required options:

- appKey: string

Optional options:

- notifications: custom adapter override (mostly useful for tests/mocks)
- apiUrl: string (default: <https://flow-push-api.vercel.app/api/v1>)
- storage: key-value storage adapter (defaults to expo-secure-store)
- fetchImpl: custom fetch implementation

Default behavior out of the box:

- Notifications provider: expo-notifications
- Storage provider: expo-secure-store
- Device platform resolution: expo-device
- Physical device identity: native device ID via react-native-device-info, with local UUID fallback

Custom storage override example:

```ts
const sdk = new FlowPushExpo({
  appKey: "your-flowpush-app-key",
  storage: {
    getItem: (key) => SecureStore.getItemAsync(key),
    setItem: (key, value) => SecureStore.setItemAsync(key, value),
    removeItem: (key) => SecureStore.deleteItemAsync(key),
  },
})
```

### requestPermissionAsync()

Requests notification permission through the notifications adapter.

### registerDeviceAsync(options?)

Registers a push token as a FlowPush device.

Options:

- deviceType?: "ios" | "android" (auto-resolved from native token type when omitted)
- provider?: "apns" | "fcm" | "hms" (default: "fcm")
- physicalId?: string
- pushToken?: string (manual token override; used as the registration token for the selected provider)
- appVersion?: string
- osVersion?: string
- deviceModel?: string

Provider note:

- Use `provider: "apns"`, `provider: "fcm"`, or `provider: "hms"` to register native device push tokens.
- The SDK resolves native tokens via `expo-notifications` `getDevicePushTokenAsync`.

Returns:

- deviceId
- pushToken
- physicalId
- deviceType

### identifyAsync(params)

Links the current device context to your app user profile.

Params:

- userId: string
- attributes?: Record<string, unknown>

### unregisterDeviceAsync(pushToken?)

Marks the device inactive in FlowPush and clears local SDK context keys.

### getDeviceContextAsync()

Returns:

- deviceId
- physicalId
- pushToken

## Notes on Current Backend Contract

The app SDK registers mobile devices through POST /sdk/mobile/devices.

This endpoint accepts token/provider/deviceType payloads and maps them into the
current device model while preserving identity lifecycle behavior.

Campaign send path:

- Native dispatch provider routing happens on backend campaign send flow.
- Retries and dead-letter recording for exhausted retry attempts are handled server-side.

## License

MIT