Notification Adapters
Push notification adapters for token registration and management.
Work in Progress: The notification adapter APIs are under active development and may change in future releases.
Notification adapters handle push notification token registration, permission requests, and notification event handling with your push notification provider.
Available Adapters
| Adapter | Package | Best For |
|---|---|---|
ExpoNotificationsAdapter | expo-notifications | Expo projects |
FirebaseMessagingAdapter | @react-native-firebase/messaging | Firebase Cloud Messaging |
WixNotificationsAdapter | react-native-notifications | Wix notifications library |
Usage
Notification adapters are passed to TeardownCore to enable push notification support:
import { TeardownCore } from '@teardown/force-updates';
import { ExpoNotificationsAdapter } from '@teardown/force-updates/expo';
import { ExpoDeviceAdapter } from '@teardown/force-updates/adapters/expo';
import { MMKVStorageAdapter } from '@teardown/force-updates/adapters/mmkv';
const teardown = new TeardownCore({
org_id: 'your-org-id',
project_id: 'your-project-id',
api_key: 'your-api-key',
storageAdapter: new MMKVStorageAdapter(),
deviceAdapter: new ExpoDeviceAdapter(),
notificationAdapter: new ExpoNotificationsAdapter(), // Optional
});
// Access notifications via core
if (teardown.notifications) {
const token = await teardown.notifications.getToken();
}Adapter Interface
All notification adapters extend the abstract NotificationAdapter class:
abstract class NotificationAdapter {
/** The notification platform this adapter supports (APNS, FCM, EXPO) */
abstract get platform(): NotificationPlatformEnum;
/** Get the current push notification token */
abstract getToken(): Promise<string | null>;
/** Request push notification permissions from the user */
abstract requestPermissions(): Promise<PermissionStatus>;
/** Subscribe to token refresh events */
abstract onTokenRefresh(listener: (token: string) => void): Unsubscribe;
/** Subscribe to foreground notification events */
abstract onNotificationReceived(listener: (notification: PushNotification) => void): Unsubscribe;
/** Subscribe to notification opened events (user taps) */
abstract onNotificationOpened(listener: (notification: PushNotification) => void): Unsubscribe;
/** Subscribe to data-only message events (silent/background push) */
abstract onDataMessage(listener: (message: DataMessage) => void): Unsubscribe;
}PermissionStatus
interface PermissionStatus {
/** Whether notifications permission is granted */
granted: boolean;
/** Whether the user can be prompted again (iOS specific) */
canAskAgain: boolean;
}PushNotification
interface PushNotification {
title?: string;
body?: string;
data?: Record<string, unknown>;
}DataMessage
interface DataMessage {
data: Record<string, unknown>;
}NotificationPlatformEnum
enum NotificationPlatformEnum {
APNS = "APNS", // Apple Push Notification Service
FCM = "FCM", // Firebase Cloud Messaging
EXPO = "EXPO", // Expo Push Notifications
}Choosing an Adapter
| If you're using... | Use this adapter |
|---|---|
| Expo with expo-notifications | ExpoNotificationsAdapter |
| Firebase Cloud Messaging | FirebaseMessagingAdapter |
| Wix react-native-notifications | WixNotificationsAdapter |
| Other push library | Implement custom adapter |
Custom Adapter
Extend the NotificationAdapter abstract class:
import {
NotificationAdapter,
NotificationPlatformEnum,
type PermissionStatus,
type PushNotification,
type DataMessage,
type Unsubscribe,
} from '@teardown/force-updates';
class CustomNotificationsAdapter extends NotificationAdapter {
get platform(): NotificationPlatformEnum {
return NotificationPlatformEnum.FCM;
}
async getToken(): Promise<string | null> {
return await myNotificationLib.getToken();
}
async requestPermissions(): Promise<PermissionStatus> {
const granted = await myNotificationLib.requestPermission();
return { granted, canAskAgain: !granted };
}
onTokenRefresh(listener: (token: string) => void): Unsubscribe {
const subscription = myNotificationLib.onTokenRefresh(listener);
return () => subscription.remove();
}
onNotificationReceived(listener: (notification: PushNotification) => void): Unsubscribe {
const subscription = myNotificationLib.onMessage((msg) => {
listener({
title: msg.notification?.title,
body: msg.notification?.body,
data: msg.data,
});
});
return () => subscription();
}
onNotificationOpened(listener: (notification: PushNotification) => void): Unsubscribe {
const subscription = myNotificationLib.onNotificationOpened((msg) => {
listener({
title: msg.notification?.title,
body: msg.notification?.body,
data: msg.data,
});
});
return () => subscription();
}
onDataMessage(listener: (message: DataMessage) => void): Unsubscribe {
const subscription = myNotificationLib.onDataMessage((msg) => {
listener({ data: msg.data ?? {} });
});
return () => subscription();
}
}