Notification Setup
This guide covers setting up push notifications for both Android (FCM) and iOS (APNs).
Overview
Twigz supports both Firebase Cloud Messaging (FCM) and Apple Push Notifications (APNs) for cross-platform push notifications.
Android Setup (FCM)
1. Firebase Project Setup
- Go to Firebase Console
- Create a new project or select existing
- Add Android app with your package name
- Download
google-services.json
2. Install Dependencies
3. Initialize Firebase
import { initializeApp } from 'firebase/app';
import { getMessaging, getToken } from 'firebase/messaging';
const firebaseConfig = {
apiKey: "your-api-key",
authDomain: "your-project.firebaseapp.com",
projectId: "your-project-id",
storageBucket: "your-project.appspot.com",
messagingSenderId: "123456789",
appId: "your-app-id"
};
const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);
4. Get FCM Token
// Get FCM token
const getFCMToken = async () => {
try {
const token = await getToken(messaging, {
vapidKey: 'your-vapid-key'
});
// Send token to your backend
await convex.mutation(api.shared.notifications.recordNativeDeviceToken, {
token,
platform: "android"
});
return token;
} catch (error) {
console.error('Error getting FCM token:', error);
}
};
iOS Setup (APNs)
1. Apple Developer Account
- Go to Apple Developer Portal
- Create App ID with Push Notifications capability
- Generate APNs certificate or key
- Configure your app for push notifications
2. Install Dependencies
npm install @react-native-async-storage/async-storage
3. Request Permission
import { requestPermissions } from 'react-native-permissions';
const requestNotificationPermission = async () => {
const result = await requestPermissions({
ios: ['alert', 'badge', 'sound'],
});
return result.ios.status === 'granted';
};
4. Get APNs Token
import messaging from '@react-native-firebase/messaging';
const getAPNsToken = async () => {
try {
const token = await messaging().getToken();
// Send token to your backend
await convex.mutation(api.shared.notifications.recordNativeDeviceToken, {
token,
platform: "ios"
});
return token;
} catch (error) {
console.error('Error getting APNs token:', error);
}
};
Sending Notifications
From Backend
// Send FCM notification
await convex.mutation(api.shared.notifications.sendFCMNotificationDirect, {
token: "fcm_token_here",
title: "New Order!",
body: "You have received a new order",
data: {
orderId: "order_123",
type: "order"
}
});
// Send APNs notification
await convex.mutation(api.shared.notifications.sendAPNsNotificationDirect, {
token: "apns_token_here",
title: "Order Update",
body: "Your order status has changed",
data: {
orderId: "order_123",
type: "order_update"
}
});
Bulk Notifications
// Send to multiple users
await convex.mutation(api.shared.notifications.sendBulkNotification, {
userIds: ["user_1", "user_2", "user_3"],
title: "Special Offer!",
body: "20% off all products today only",
data: {
type: "promotion",
discount: "20"
}
});
Notification Types
Order Notifications
// New order notification
const sendNewOrderNotification = async (storeId: string, orderId: string) => {
const store = await convex.query(api.stores.queries.getStoreByAuthenticatedOwner, {
storeId
});
if (store?.deviceTokens?.length) {
await convex.mutation(api.shared.notifications.sendNotificationToUser, {
userId: store.ownerId,
title: "New Order Received!",
body: `Order #${orderId} is ready for processing`,
data: { orderId, type: "new_order" }
});
}
};
Price Change Notifications
// Price change notification
const sendPriceChangeNotification = async (productId: string, oldPrice: number, newPrice: number) => {
const product = await convex.query(api.shared.products.getProductById, { productId });
if (product?.likedBy?.length) {
await convex.mutation(api.shared.notifications.sendBulkNotification, {
userIds: product.likedBy,
title: "Price Drop Alert!",
body: `${product.name} price dropped from ${oldPrice} to ${newPrice} AED`,
data: { productId, type: "price_change" }
});
}
};
Testing Notifications
Test Notification
// Send test notification
await convex.mutation(api.shared.notifications.sendTestNotification, {
userId: "user_123",
title: "Test Notification",
body: "This is a test notification"
});
Debug Notifications
// Debug user notifications
const debugInfo = await convex.query(api.shared.notifications.debugUserNotifications, {
userId: "user_123"
});
console.log("User tokens:", debugInfo.tokens);
console.log("Recent notifications:", debugInfo.recentNotifications);
Best Practices
- Request permission before sending notifications
- Handle token refresh for long-lived apps
- Personalize notifications based on user preferences
- Test thoroughly on both platforms
- Monitor delivery rates and user engagement
Always test notifications on real devices as simulators may not support all notification features.