React Native Package Documentation
The React Native package is for mobile apps that need an in-app notification inbox plus mobile push-device registration. It uses the same user-session token flow as the web React package, not the server-side send API.
What This Package Does
- • Fetches in-app notifications for the authenticated app user
- • Marks notifications read and deletes them
- • Registers Expo, FCM, or APNs tokens against the notifications backend
- • Lets your app attach native push listeners through an adapter
- • Reads typed mobile payload metadata for deep links, actions, badges, and local scheduling instructions
- • Fetches and updates user notification preferences through the authenticated user session
What It Does Not Do
- • It does not send notifications directly from the mobile client
- • It does not replace Expo Notifications, FCM, or APNs setup in your mobile app
- • It does not register an application with provider credentials from the device
Use appInstanceUrl when your backend session is cookie-based. Use loginFunction when your native app needs to attach a bearer token or reuse an existing API client.
Recommended Architecture
Keep the same separation already used on the web side:
- Your app backend exposes a notification auth endpoint.
- That backend endpoint calls the core SDK `login(...)` method.
- The React Native app calls that backend endpoint through `loginFunction` or `appInstanceUrl`.
- After permission is granted, the mobile app registers its push token through `usePushNotifications`.
Auth response contract
{
"token": "notification-user-session-jwt"
}Installation
npm install @sparkstrand/notifications-react-nativeBasic In-App Usage
import { useNotifications } from '@sparkstrand/notifications-react-native';
export function NotificationsScreen() {
const {
notifications,
unreadCount,
markAsRead,
markAllAsRead,
deleteNotification,
refreshNotifications,
} = useNotifications({
loginFunction: async () => {
const response = await fetch('https://your-app.com/api/notifications/auth', {
method: 'POST',
headers: { Authorization: 'Bearer app-session-token' },
});
return response.json();
},
enablePolling: true,
});
return null;
}Push Registration With Expo
import { useEffect } from 'react';
import * as Notifications from 'expo-notifications';
import Constants from 'expo-constants';
import { usePushNotifications } from '@sparkstrand/notifications-react-native';
const pushAdapter = {
isSupported: () => true,
getPermissionStatus: async () => {
const settings = await Notifications.getPermissionsAsync();
return settings.status === 'undetermined' ? 'not-determined' : settings.status;
},
requestPermission: async () => {
const settings = await Notifications.requestPermissionsAsync();
return settings.status === 'undetermined' ? 'not-determined' : settings.status;
},
getRegistration: async () => {
const token = await Notifications.getExpoPushTokenAsync({
projectId: Constants.expoConfig?.extra?.eas?.projectId,
});
return {
pushToken: token.data,
provider: 'expo',
platform: Constants.platform?.ios ? 'ios' : 'android',
deviceId: Constants.sessionId,
appVersion: Constants.expoConfig?.version,
};
},
};
export function PushSetup() {
const { requestPermission, registerDevice } = usePushNotifications({
loginFunction: async () => {
const response = await fetch('https://your-app.com/api/notifications/auth', {
method: 'POST',
headers: { Authorization: 'Bearer app-session-token' },
});
return response.json();
},
pushAdapter,
});
useEffect(() => {
const setup = async () => {
const status = await requestPermission();
if (status === 'granted' || status === 'provisional') {
await registerDevice();
}
};
void setup();
}, [registerDevice, requestPermission]);
return null;
}Supported Mobile Notification Surfaces
- • Remote push notifications delivered through Expo, FCM, or APNs
- • In-app inbox notifications fetched from this notifications system
- • Local or scheduled device notifications managed by the mobile app itself
- • Silent or data-only pushes for background refresh, handled by the chosen native push library
- • Actionable notifications and deep links, also handled in the consuming app
WebView Shell Apps
Some mobile apps are authenticated WebView shells. In that setup, the native layer may not be able to call the auth route with the same web session directly.
- Keep the shared auth route at
/api/notifications/auth. - Let the web app inside the WebView fetch that route with its existing session.
- Bridge the returned notification token to native through
postMessageor injected JavaScript. - Pass a
loginFunctionintousePushNotificationsthat resolves with the bridged token.
Current Backend Endpoints
- • `GET /api/notifications/app/user`
- • `GET /api/notifications/app/user/[notificationId]`
- • `PUT /api/notifications/app/user/mark-as-read`
- • `DELETE /api/notifications/app/user`
- • `GET|POST|DELETE /api/notifications/app/user/devices`
- • `GET|PUT /api/notifications/app/user/preferences`