@54vie/push - Push Notifications
Module for managing push notifications for 54VIE Super App, supporting FCM/APNs and local notifications.
Installation
pnpm add @54vie/push
Setup
import { PushProvider } from '@54vie/push';
function App() {
return (
<PushProvider
onNotificationReceived={(notification) => {
console.log('Received:', notification);
}}
onNotificationOpened={(notification) => {
// Navigate based on notification data
if (notification.data?.orderId) {
navigation.navigate('OrderDetail', { id: notification.data.orderId });
}
}}
>
<MainApp />
</PushProvider>
);
}
Permission & Token
import { usePush, pushService } from '@54vie/push';
function NotificationSetup() {
const {
token,
isPermissionGranted,
requestPermission,
getToken,
} = usePush();
useEffect(() => {
if (!isPermissionGranted) {
requestPermission();
}
}, []);
// Send token to server
useEffect(() => {
if (token) {
api.post('/devices/register', { token });
}
}, [token]);
}
Topic Subscription
import { pushService } from '@54vie/push';
// Subscribe to topics
await pushService.subscribeToTopic('promotions');
await pushService.subscribeToTopic('news');
// Unsubscribe
await pushService.unsubscribeFromTopic('promotions');
Local Notifications
import { useLocalNotification, localNotificationService } from '@54vie/push';
function OrderConfirmation() {
const { schedule, cancel, cancelAll } = useLocalNotification();
// Schedule notification
const remindPickup = async () => {
const id = await schedule({
title: 'Order Ready',
body: 'Your order is ready for pickup!',
data: { orderId: '123' },
scheduledAt: new Date(Date.now() + 30 * 60 * 1000), // 30 min
});
// Save ID to cancel later if needed
setReminderId(id);
};
// Cancel
const cancelReminder = () => {
cancel(reminderId);
};
}
Recurring Notifications
await schedule({
title: 'Daily Reminder',
body: 'Check your orders!',
repeatType: 'day',
scheduledAt: new Date(), // Start time
});
Action Buttons
// Create category with actions
await localNotificationService.createCategory('order', [
{ id: 'accept', title: 'Accept', destructive: false },
{ id: 'reject', title: 'Reject', destructive: true },
]);
// Schedule with category
await schedule({
title: 'New Order',
body: 'Order #123 received',
category: 'order',
data: { orderId: '123' },
});
Notification Center
import { useNotifications, NotificationList } from '@54vie/push';
function NotificationScreen() {
const {
notifications,
unreadCount,
markAsRead,
markAllAsRead,
deleteNotification,
clear,
} = useNotifications();
return (
<View>
<Header>
<Text>Notifications ({unreadCount})</Text>
<Button onPress={markAllAsRead}>Mark all read</Button>
</Header>
<NotificationList
notifications={notifications}
onPress={(n) => {
markAsRead(n.id);
handleNavigation(n.data);
}}
onDelete={(n) => deleteNotification(n.id)}
/>
</View>
);
}
Badge Management
import { pushService } from '@54vie/push';
// Set badge count
await pushService.setBadgeCount(5);
// Clear badge
await pushService.clearBadge();
Notification Channels (Android)
import { NotificationChannel } from '@54vie/push';
// Create channels (call at app start)
await NotificationChannel.create({
id: 'payments',
name: 'Payment Notifications',
importance: 'high',
sound: 'payment_sound',
vibration: true,
});
await NotificationChannel.create({
id: 'promotions',
name: 'Promotions',
importance: 'default',
});
Deep Linking
import { DeepLinkRouter } from '@54vie/push';
// Register routes
DeepLinkRouter.register('order/:orderId', ({ orderId }) => {
navigation.navigate('OrderDetail', { id: orderId });
});
DeepLinkRouter.register('miniapp/:appId', ({ appId }) => {
navigation.navigate('MiniProgram', { appId });
});
// Handle notification tap
onNotificationOpened((notification) => {
if (notification.data?.deepLink) {
DeepLinkRouter.navigate(notification.data.deepLink);
}
});
Components
import { NotificationBadge, NotificationItem } from '@54vie/push';
// Badge with count
<NotificationBadge>
<Icon name="bell" />
</NotificationBadge>
// Notification item
<NotificationItem
notification={notification}
onPress={() => handlePress(notification)}
onDelete={() => handleDelete(notification.id)}
/>