Notifications Feature
The Notifications feature provides real-time alerts for user activities, interactions, and important updates across the platform.
What Notifications Do in This Project
The notification system is a central communication hub that keeps users informed about all activities happening in their social network. It serves multiple critical purposes:
1. User Engagement & Retention
- Keeps users connected to their social network by alerting them to interactions
- Encourages users to return to the platform when they receive notifications
- Increases engagement by making users aware of new content, messages, and interactions
2. Real-Time Activity Awareness
- Provides instant updates when someone interacts with your content (likes, comments, shares)
- Alerts you to new friend requests and relationship changes
- Notifies you of new messages and conversations
- Keeps you informed about system events and important announcements
3. Actionable Alerts
- Each notification includes an
actionUrlthat directs users to the relevant content actionDatacontains context (post ID, friend request ID, etc.) for quick navigation- Enables users to quickly respond to interactions without searching
4. Multi-Channel Delivery
- Real-time WebSocket delivery via SignalR for instant notifications
- Web Push for browser alerts when the tab is in the background (see Web Push and Expo Push)
- Expo Push for mobile app alerts when the app is in the background (see Web Push and Expo Push)
- Email notifications (optional) for important events
- In-app notification center for viewing notification history
5. Notification Management
- Users can organize notifications by status (read, unread, dismissed, archived)
- Filter notifications by type, priority, and date
- Manage notification preferences to control what they receive
- Set quiet hours to avoid notifications during specific times
6. System Integration
- Automatically triggered by domain events (post liked, comment added, friend request sent)
- Integrated with background workers for processing and delivery
- Uses MongoDB for persistent storage and Redis for caching
- Supports notification expiration for temporary alerts
Overview
Notifications enable users to:
- Stay updated on social interactions (likes, comments, mentions)
- Receive friend request notifications
- Get alerts for messages and conversations
- Track important system announcements
- Manage notification preferences
- Access notification history
Notification Priority
Priority indicates the importance and urgency of a notification. It helps users and the system determine which notifications need immediate attention versus those that can be reviewed later.
What Priority Affects
- Display Order: High-priority notifications appear first in notification lists
- Visual Indicators: Different styling (colors, icons) based on priority
- Filtering: Users can filter to show only high-priority notifications
- Push Notifications: Higher priority notifications may trigger push alerts even with quiet hours enabled
- Badge Counts: Separate counts for high-priority and urgent notifications
- User Experience: Helps users focus on important notifications first
Priority Levels
| Priority | Description | Use Case | Examples |
|---|---|---|---|
| Low | Non-urgent notifications that don't require immediate attention | General updates, informational messages | Friend declined request, user unfollowed you, post ready |
| Normal | Standard notifications for typical social interactions | Most social interactions and activities | Post liked, comment added, friend accepted, user followed |
| High | Important notifications that should be noticed soon | Actions requiring user response or attention | Friend requests, mentions, direct messages, group invites |
| Urgent | Critical notifications requiring immediate attention | System-critical events, security issues | Security alerts, system failures, account security issues |
How Priority is Determined
Priority is automatically assigned based on the notification type:
- Friend Requests →
High(requires user decision) - Mentions & Tags →
High(direct user interaction) - Direct Messages →
High(personal communication) - Security Alerts →
Urgent(critical security events) - System Announcements →
High(important platform updates) - Post Likes/Comments →
Normal(standard social interaction) - Friend Declined →
Low(informational, no action needed)
Using Priority in Your Application
For Users:
- Filter notifications by priority to focus on important ones
- High-priority notifications appear at the top of your list
- Urgent notifications may bypass quiet hours settings
For Developers:
- Use priority to sort notifications:
ORDER BY priority DESC, createdAt DESC - Filter API calls:
GET /api/notification/paged?priority=High - Display visual indicators (badges, colors) based on priority
- Show separate unread counts:
GET /api/notification/unread-countreturnshighPriorityCountandurgentCount
Notification Status
Notifications can have different statuses:
| Status | Description |
|---|---|
| Unread | Notification hasn't been viewed |
| Read | Notification has been viewed |
| Dismissed | User dismissed the notification |
| Archived | Notification has been archived |
Notification Types
The system supports comprehensive notification types covering all aspects of social interaction:
Friend-Related Notifications
| Type | Description | Trigger | Priority |
|---|---|---|---|
| FriendRequest | New friend request received | Someone sends you a friend request | High |
| FriendAccepted | Friend request accepted | Someone accepts your friend request | Normal |
| FriendDeclined | Friend request declined | Someone declines your friend request | Low |
| FriendRemoved | Friend removed | Someone unfriends you | Normal |
Post-Related Notifications
| Type | Description | Trigger | Priority |
|---|---|---|---|
| PostLiked | Someone liked your post | User reacts to your post | Normal |
| PostCommented | New comment on your post | User comments on your post | Normal |
| PostShared | Someone shared your post | User shares your post | Normal |
| PostMentioned | You were mentioned in a post | User mentions you in a post | High |
| PostTagged | You were tagged in a post | User tags you in a post | High |
| PostReady | Your post is ready | Post processing completed | Low |
Story-Related Notifications
| Type | Description | Trigger | Priority |
|---|---|---|---|
| StoryReady | Your story is ready | Story processing completed | Low |
| StoryViewed | Someone viewed your story | User views your story | Low |
| StoryReacted | Someone reacted to your story | User reacts to your story | Normal |
Messaging Notifications
| Type | Description | Trigger | Priority |
|---|---|---|---|
| DirectMessage | New direct message | User sends you a message | High |
| GroupMessage | New group message | Message in a group you're in | Normal |
Follow Notifications
| Type | Description | Trigger | Priority |
|---|---|---|---|
| UserFollowed | Someone started following you | User follows your profile | Normal |
| UserUnfollowed | Someone unfollowed you | User unfollows your profile | Low |
Group Notifications
| Type | Description | Trigger | Priority |
|---|---|---|---|
| GroupInvite | Invited to a group | Someone invites you to a group | High |
| GroupJoined | Joined a group | You join a group | Normal |
| GroupLeft | Left a group | You leave a group | Low |
| GroupPostCreated | New post in group | Post created in a group you're in | Normal |
| GroupRoleChanged | Group role changed | Your role in a group changed | Normal |
Event Notifications
| Type | Description | Trigger | Priority |
|---|---|---|---|
| EventInvite | Invited to an event | Someone invites you to an event | High |
| EventReminder | Event reminder | Event is coming up | Normal |
| EventUpdated | Event updated | Event details changed | Normal |
| EventCancelled | Event cancelled | Event was cancelled | High |
Birthday & Anniversary
| Type | Description | Trigger | Priority |
|---|---|---|---|
| Birthday | Your birthday reminder | Your birthday | Normal |
| FriendBirthday | Friend's birthday | Friend's birthday | Normal |
| Anniversary | Anniversary reminder | Relationship anniversary | Normal |
System Notifications
| Type | Description | Trigger | Priority |
|---|---|---|---|
| SystemAnnouncement | System announcement | Important platform updates | High |
| SecurityAlert | Security notification | Security-related events | Urgent |
| AccountUpdated | Account updated | Account settings changed | Normal |
Achievement Notifications
| Type | Description | Trigger | Priority |
|---|---|---|---|
| FirstPost | First post milestone | You create your first post | Normal |
| PopularPost | Popular post | Your post becomes popular | Normal |
| MilestoneReached | Milestone reached | You reach a milestone | Normal |
General
| Type | Description | Trigger | Priority |
|---|---|---|---|
| General | General notification | Custom notifications | Normal |
How Notifications Work
Notification Lifecycle
- Creation: Notification is created when a domain event occurs (e.g., post liked, friend request sent)
- Storage: Saved to MongoDB for persistence and history
- Queue: Published to message queue (RabbitMQ) for processing
- Processing: WebSocketWorker processes the notification
- Delivery: Sent via SignalR WebSocket to connected clients in real-time
- Status Updates: User interactions (read, dismiss, archive) update notification status
Notification Storage
- MongoDB: Primary storage for all notifications (persistent, queryable)
- Redis: Caching for unread counts and frequently accessed notifications
- SignalR Hub: Real-time delivery to connected clients
Automatic Notification Triggers
Notifications are automatically created when these events occur:
- Post Interactions: Like, comment, share, mention
- Friend Requests: Send, accept, decline
- Messages: New direct message or group message
- Follows: User follows or unfollows you
- System Events: Security alerts, announcements, birthdays
- Media Processing: When uploaded media is ready
- Achievements: First post, popular post, milestones
Viewing Notifications
Get Paginated Notifications
Purpose: Retrieve a paginated list of notifications with advanced filtering capabilities. This is the primary endpoint for displaying notifications in the notification center.
Use Cases:
- Display notifications in a notification dropdown or center
- Filter notifications by type (e.g., only show friend requests)
- Show only unread notifications
- Filter by priority (e.g., show high-priority notifications first)
- Paginate through notification history
When to Use:
- Loading the notification center on app startup
- Refreshing the notification list
- Filtering notifications by specific criteria
- Implementing infinite scroll for notification history
Retrieve notifications with advanced filtering:
GET /api/notification/paged?page=1&pageSize=20&status=Unread&type=PostLiked&priority=High&includeExpired=false
Authorization: Bearer {token}
Query Parameters:
page(optional) - Page number (default: 1)pageSize(optional) - Items per page (default: 20)status(optional) - Filter by status:Unread,Read,Dismissed,Archivedtype(optional) - Filter by type:PostLiked,FriendRequest, etc.priority(optional) - Filter by priority:Low,Normal,High,UrgentincludeExpired(optional) - Include expired notifications (default: false)
Response:
{
"success": true,
"data": {
"items": [
{
"id": "notification-123",
"userId": "user-456",
"senderId": "user-789",
"type": "PostLiked",
"status": "Unread",
"priority": "Normal",
"title": "John Doe liked your post",
"message": "John Doe liked your post 'Amazing sunset!'",
"imageUrl": "https://...",
"actionUrl": "/posts/post-123",
"actionData": "{\"postId\":\"post-123\"}",
"createdAt": "2024-01-15T10:00:00Z",
"readAt": null,
"expiresAt": null,
"isPersistent": true,
"metadata": {}
}
],
"totalCount": 45,
"page": 1,
"pageSize": 20,
"totalPages": 3
}
}
Get Unread Count
Purpose: Get the total count of unread notifications for displaying a badge or indicator. This endpoint is optimized for frequent polling without loading full notification data.
Use Cases:
- Display a notification badge with unread count (e.g., "5" on a bell icon)
- Show unread count in the navigation bar
- Update the count in real-time when notifications are received
- Filter by priority to show only high-priority unread count
When to Use:
- Polling for unread count updates (every 30-60 seconds)
- Displaying notification indicators in the UI
- Updating badge counts after marking notifications as read
- Showing separate counts for high-priority and urgent notifications
Performance Note: This endpoint is lightweight and can be called frequently without performance impact.
Get the count of unread notifications:
GET /api/notification/unread-count?includeExpired=false
Authorization: Bearer {token}
Response:
{
"success": true,
"data": {
"unreadCount": 5,
"highPriorityCount": 1,
"urgentCount": 0
}
}
Get Notification by ID
Purpose: Retrieve detailed information about a specific notification. Used when a user clicks on a notification to view full details or navigate to the related content.
Use Cases:
- Viewing notification details when clicked
- Getting full notification data including metadata
- Validating notification exists and user has access
- Loading notification context before navigation
When to Use:
- User clicks on a notification in the list
- Opening notification details in a modal or detail view
- Validating notification before performing an action
- Getting action data for navigation
Security: Only returns notifications that belong to the authenticated user.
Retrieve a specific notification:
GET /api/notification/{notificationId}
Authorization: Bearer {token}
Response:
{
"success": true,
"data": {
"id": "notification-123",
"userId": "user-456",
"senderId": "user-789",
"type": "FriendRequest",
"status": "Unread",
"priority": "High",
"title": "New Friend Request",
"message": "John Doe sent you a friend request",
"imageUrl": "https://...",
"actionUrl": "/friends/requests",
"actionData": "{\"friendshipId\":123}",
"createdAt": "2024-01-15T10:00:00Z",
"readAt": null,
"expiresAt": null
}
}
Get Notification Statistics
Purpose: Get aggregated statistics about notifications for analytics, insights, and user dashboards. Provides counts by type, priority, and status.
Use Cases:
- Display notification analytics in user dashboard
- Show notification trends over time
- Analyze notification engagement (read rates, types)
- Generate reports on notification activity
When to Use:
- Loading analytics dashboard
- Generating notification reports
- Analyzing user engagement with notifications
- Displaying notification activity over time periods
Analytics Provided:
- Total notification counts
- Breakdown by notification type
- Breakdown by priority level
- Status distribution (read, unread, dismissed, archived)
- Time-based filtering for trends
Get notification statistics for analytics:
GET /api/notification/stats?fromDate=2024-01-01&toDate=2024-12-31
Authorization: Bearer {token}
Query Parameters:
fromDate(optional) - Start date for statisticstoDate(optional) - End date for statistics
Response:
{
"success": true,
"data": {
"totalNotifications": 150,
"unreadCount": 5,
"readCount": 140,
"dismissedCount": 3,
"archivedCount": 2,
"byType": {
"PostLiked": 45,
"PostCommented": 30,
"FriendRequest": 20,
"DirectMessage": 25,
"Other": 30
},
"byPriority": {
"Low": 50,
"Normal": 80,
"High": 18,
"Urgent": 2
}
}
}
Managing Notifications
Create Notification
Purpose: Manually create a notification (typically used by admin or system processes). Most notifications are created automatically by domain events, but this endpoint allows programmatic creation.
Use Cases:
- Admin creating system announcements
- Scheduled notifications (birthdays, reminders)
- External systems creating notifications
- Testing and development
When to Use:
- Creating custom notifications programmatically
- Admin panel for sending announcements
- Background jobs creating scheduled notifications
- Integration with external services
Note: In most cases, notifications are automatically created by domain event handlers. Use this endpoint only when manual creation is needed.
Mark Notification as Read
Purpose: Mark a single notification as read when the user views it. Updates the notification status and records the read timestamp.
Use Cases:
- User clicks on a notification
- User views notification details
- Marking notification as read when displayed
- Updating notification status for tracking
When to Use:
- User opens a notification
- Notification is displayed in the UI
- User navigates to the related content
- Auto-marking as read when viewed
Important: Uses optimistic concurrency control with rowVersion to prevent conflicts when multiple clients update the same notification.
Mark a single notification as read:
PUT /api/notification/mark-status
Authorization: Bearer {token}
Content-Type: application/json
{
"id": "notification-123",
"status": "Read",
"rowVersion": "base64-encoded-version"
}
Mark All as Read
Purpose: Mark all unread notifications as read in a single operation. Provides a "Mark all as read" functionality for users who want to clear their notification list.
Use Cases:
- User clicks "Mark all as read" button
- Bulk clearing of notifications
- Resetting notification state
- Quick notification management
When to Use:
- User wants to clear all unread notifications at once
- Bulk notification management
- Resetting notification state after reviewing all
Options:
includeExpired: Whether to mark expired notifications as read (default: false)
Performance: Efficiently updates all matching notifications in a single database operation.
Mark all notifications as read:
PUT /api/notification/mark-all-read?includeExpired=false
Authorization: Bearer {token}
Response:
{
"success": true,
"message": "All notifications marked as read",
"data": {
"updatedCount": 5
}
}
Dismiss Notification
Purpose: Dismiss a notification to remove it from the active notification list without deleting it. Dismissed notifications are hidden but can be viewed in archived/dismissed sections.
Use Cases:
- User swipes away a notification
- User dismisses a notification they don't want to see
- Removing notifications from active view without deleting
- Temporary hiding of notifications
When to Use:
- User wants to hide a notification without deleting it
- Dismissing notifications that are not relevant
- Clearing notifications from view temporarily
Note: Dismissed notifications are still stored and can be retrieved with status filtering.
Dismiss a notification:
PUT /api/notification/{notificationId}/dismiss
Authorization: Bearer {token}
Content-Type: application/json
"base64-encoded-row-version"
Archive Notification
Purpose: Archive a notification for long-term storage. Archived notifications are kept for history but removed from active notification lists.
Use Cases:
- User wants to keep important notifications for later reference
- Organizing notifications into archives
- Long-term notification storage
- Keeping notification history without cluttering active list
When to Use:
- User wants to save important notifications
- Organizing notification history
- Moving notifications to archive for later review
Difference from Dismiss: Archived notifications are typically kept longer and are considered "saved" rather than "hidden".
Archive a notification:
PUT /api/notification/{notificationId}/archive
Authorization: Bearer {token}
Content-Type: application/json
"base64-encoded-row-version"
Delete Notification
Purpose: Permanently delete a notification from the database. This action cannot be undone.
Use Cases:
- User wants to permanently remove a notification
- Cleaning up old or unwanted notifications
- Removing sensitive or irrelevant notifications
- Notification cleanup and maintenance
When to Use:
- User explicitly wants to delete a notification
- Removing notifications that are no longer needed
- Permanent cleanup of notification history
Warning: This action is permanent. Consider using "Dismiss" or "Archive" if you might need the notification later.
Delete a notification:
DELETE /api/notification/{notificationId}
Authorization: Bearer {token}
Real-time Notifications
How Real-Time Delivery Works
The notification system uses a multi-layered architecture for real-time delivery:
- Domain Event: When an action occurs (e.g., post liked), a domain event is raised
- Event Handler:
NotificationCreatedDomainEventHandlerprocesses the event - Message Queue: Notification is published to RabbitMQ queue
- WebSocketWorker: Background worker consumes from queue
- SignalR Hub: Worker sends notification via SignalR to connected clients
- Client Receives: Frontend receives notification instantly via WebSocket
This architecture ensures:
- Scalability: Workers can be scaled independently
- Reliability: Queue ensures notifications aren't lost
- Performance: Non-blocking, asynchronous processing
- Real-time: Instant delivery to connected clients
WebSocket Connection
Purpose: Establish a persistent WebSocket connection to receive notifications in real-time without polling. This provides instant notification delivery and reduces server load.
Use Cases:
- Real-time notification delivery
- Instant updates when notifications are created
- Live notification count updates
- Push notification delivery
When to Use:
- App startup: Connect to receive real-time notifications
- Always maintain connection while app is active
- Reconnect automatically on disconnection
- Handle connection lifecycle (connect, disconnect, reconnect)
Notifications are delivered in real-time via SignalR WebSocket:
// Connect to SignalR hub
const connection = new signalR.HubConnectionBuilder()
.withUrl("/notificationHub", {
accessTokenFactory: () => token
})
.build();
// Listen for new notifications
connection.on("ReceiveNotification", (notification) => {
console.log("New notification:", notification);
// Update UI with new notification
});
// Listen for notification updates
connection.on("NotificationRead", (notificationId) => {
console.log("Notification read:", notificationId);
// Update notification status in UI
});
// Listen for unread count updates
connection.on("NotificationCountUpdated", (count) => {
console.log("Unread count:", count);
// Update badge count
});
// Start connection
connection.start().then(() => {
console.log("Connected to notification hub");
});
SignalR Events
| Event | Description | Payload |
|---|---|---|
ReceiveNotification | New notification received | { notification: {...} } |
NotificationRead | Notification marked as read | { notificationId: "..." } |
NotificationCountUpdated | Unread count changed | { count: 5 } |
NotificationDeleted | Notification deleted | { notificationId: "..." } |
NotificationBatchRead | Multiple notifications read | { count: 5 } |
Notification Preferences
Update Preferences
Configure which notifications you want to receive:
PUT /api/Notification (or user/settings endpoints for notification preferences)
Authorization: Bearer {token}
Content-Type: application/json
{
"friendRequestNotifications": true,
"postReactionNotifications": true,
"commentNotifications": true,
"messageNotifications": true,
"emailNotifications": false,
"pushNotifications": true,
"quietHoursEnabled": true,
"quietHoursStart": "22:00",
"quietHoursEnd": "08:00"
}
Push Notifications
The app supports Web Push (browser) and Expo Push (mobile) for chat and call notifications when the tab or app is in the background. Subscriptions and tokens are stored by the API; dedicated workers (WebPushNotificationWorker, ExpoPushNotificationWorker) consume chat/call events from RabbitMQ and send push to recipients.
For full setup, API endpoints, workers, and troubleshooting, see Web Push and Expo Push.
Web Push (browser) – quick reference
- Subscribe: User enables notifications in Settings → Notification; frontend registers subscription with
POST /api/push-subscriptions(endpoint, p256dh, auth). - Test:
POST /api/push-subscriptions/test(or “Send test notification” in Settings) sends a test push directly from the API (no worker needed). - Chat/call push: API publishes to RabbitMQ; WebPushNotificationWorker consumes and sends web push. Requires RabbitMQ and the worker to be running.
Expo Push (mobile) – quick reference
- Register: Mobile app sends Expo push token with
POST /api/push-subscriptions/expoafter login. - Chat/call push: API publishes to RabbitMQ; ExpoPushNotificationWorker consumes and sends push via Expo. Requires RabbitMQ and the worker to be running.
Notification Expiration
Some notifications can have expiration dates:
- Temporary Notifications: Expire after a set time
- Persistent Notifications: Remain until manually dismissed
- Event Notifications: Expire when the event is no longer relevant
Check the expiresAt field to determine if a notification has expired.
Notification Architecture
System Components
-
Domain Layer (
Domain/Modules/Notification)Notificationentity with business logic- Notification value objects (Type, Status, Priority)
- Domain events for notification creation
-
Application Layer (
Application/Modules/Notification)- Commands: Create, Update, Delete notifications
- Queries: Get notifications, stats, counts
- Event handlers for automatic notification creation
-
Infrastructure Layer
- MongoDB Repository: Persistent storage
- Redis Cache: Unread counts and caching
- RabbitMQ: Message queue for async processing
- SignalR Hub: Real-time WebSocket delivery
-
Workers
- WebSocketWorker: Processes notifications from queue and delivers via SignalR
- Background Jobs: Scheduled notifications (birthdays, reminders)
Notification Flow
User Action (e.g., Like Post)
↓
Domain Event Raised (PostLikedDomainEvent)
↓
Event Handler (PostLikedDomainEventHandler)
↓
Create Notification Command
↓
Save to MongoDB
↓
Publish Domain Event (NotificationCreatedDomainEvent)
↓
NotificationCreatedDomainEventHandler
↓
Publish to RabbitMQ Queue
↓
WebSocketWorker Consumes
↓
Send via SignalR Hub
↓
Client Receives Real-Time Notification
Data Storage
- MongoDB: All notifications stored with full history
- Redis: Caching for performance (unread counts, recent notifications)
- Optimistic Concurrency: RowVersion prevents update conflicts
Best Practices
For Users
- Regular Check-ins: Review notifications regularly to stay updated
- Mark as Read: Keep your notification list organized
- Configure Preferences: Adjust settings to receive only relevant notifications
- Use Quiet Hours: Enable quiet hours to avoid notifications during sleep
- Archive Old Notifications: Archive notifications you want to keep but don't need to see
- Filter by Priority: Focus on high-priority notifications first
- Use Action URLs: Click notifications to navigate directly to related content
For Developers
- Real-time Updates: Always use WebSocket for instant notification delivery
- Batch Operations: Use batch read operations for better performance
- Filtering: Implement client-side filtering for better UX
- Pagination: Always use pagination for notification lists
- Error Handling: Handle WebSocket disconnections gracefully
- Polling Fallback: Implement polling as fallback if WebSocket fails
- Optimistic Updates: Update UI optimistically before server confirmation
- Cache Unread Count: Cache unread count to reduce API calls
- Debounce Updates: Debounce rapid status updates to reduce server load
- Handle Expiration: Check
expiresAtbefore displaying notifications
API Reference
Notification endpoints are under api/Notification (paged, unread count, mark read, mark all read) and api/Announcement for admin. See the API Intro for the route table and Push Notifications for Web Push and Expo.
Related Features
- Web Push and Expo Push - Browser and mobile push for chat/call
- Messaging Feature - Message notifications
- Posts Feature - Post interaction notifications
- Relationships Feature - Friend request notifications
- API Intro - Real-time (SignalR) · Architecture