Real-time Notifications
Notification system: in-app toast, bell icon counter, push notification ke device. Tiga channel berbeda, satu trigger.
Architecture
Event → Notification Service → DB (persist)
→ WebSocket/SSE (in-app)
→ Push API (browser push)
→ FCM/APNS (mobile push)
In-app Notifications
// Server: emit saat notification dibuat
async function createNotification(userId, data) {
const notification = await db.notifications.create({
data: { userId, ...data, read: false },
});
// Push via WebSocket
io.to(`user:${userId}`).emit("notification:new", notification);
return notification;
}
// Client: React hook
function useNotifications() {
const [notifications, setNotifications] = useState([]);
const [unreadCount, setUnreadCount] = useState(0);
useEffect(() => {
socket.on("notification:new", (notif) => {
setNotifications(prev => [notif, ...prev]);
setUnreadCount(prev => prev + 1);
showToast(notif.message); // toast popup
});
}, []);
const markRead = async (id) => {
await fetch(`/api/notifications/${id}/read`, { method: "POST" });
setNotifications(prev =>
prev.map(n => n.id === id ? { ...n, read: true } : n)
);
setUnreadCount(prev => prev - 1);
};
return { notifications, unreadCount, markRead };
}
Browser Push Notifications
// Request permission
const permission = await Notification.requestPermission();
if (permission === "granted") {
// Register service worker for push
const registration = await navigator.serviceWorker.register("/sw.js");
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: VAPID_PUBLIC_KEY,
});
// Send subscription to server
await fetch("/api/push/subscribe", {
method: "POST",
body: JSON.stringify(subscription),
});
}
// Service Worker (sw.js)
self.addEventListener("push", (event) => {
const data = event.data.json();
self.registration.showNotification(data.title, {
body: data.body,
icon: "/icon-192.png",
});
});
Notification Preferences
- Per-type toggle (mentions: on, likes: off)
- Quiet hours (no notifications 22:00-08:00)
- Digest mode (batch notifications, send hourly)