Skip to main content

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 actionUrl that directs users to the relevant content
  • actionData contains 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

  1. Display Order: High-priority notifications appear first in notification lists
  2. Visual Indicators: Different styling (colors, icons) based on priority
  3. Filtering: Users can filter to show only high-priority notifications
  4. Push Notifications: Higher priority notifications may trigger push alerts even with quiet hours enabled
  5. Badge Counts: Separate counts for high-priority and urgent notifications
  6. User Experience: Helps users focus on important notifications first

Priority Levels

PriorityDescriptionUse CaseExamples
LowNon-urgent notifications that don't require immediate attentionGeneral updates, informational messagesFriend declined request, user unfollowed you, post ready
NormalStandard notifications for typical social interactionsMost social interactions and activitiesPost liked, comment added, friend accepted, user followed
HighImportant notifications that should be noticed soonActions requiring user response or attentionFriend requests, mentions, direct messages, group invites
UrgentCritical notifications requiring immediate attentionSystem-critical events, security issuesSecurity alerts, system failures, account security issues

How Priority is Determined

Priority is automatically assigned based on the notification type:

  • Friend RequestsHigh (requires user decision)
  • Mentions & TagsHigh (direct user interaction)
  • Direct MessagesHigh (personal communication)
  • Security AlertsUrgent (critical security events)
  • System AnnouncementsHigh (important platform updates)
  • Post Likes/CommentsNormal (standard social interaction)
  • Friend DeclinedLow (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-count returns highPriorityCount and urgentCount

Notification Status

Notifications can have different statuses:

StatusDescription
UnreadNotification hasn't been viewed
ReadNotification has been viewed
DismissedUser dismissed the notification
ArchivedNotification has been archived

Notification Types

The system supports comprehensive notification types covering all aspects of social interaction:

TypeDescriptionTriggerPriority
FriendRequestNew friend request receivedSomeone sends you a friend requestHigh
FriendAcceptedFriend request acceptedSomeone accepts your friend requestNormal
FriendDeclinedFriend request declinedSomeone declines your friend requestLow
FriendRemovedFriend removedSomeone unfriends youNormal

Post-Related Notifications

TypeDescriptionTriggerPriority
PostLikedSomeone liked your postUser reacts to your postNormal
PostCommentedNew comment on your postUser comments on your postNormal
PostSharedSomeone shared your postUser shares your postNormal
PostMentionedYou were mentioned in a postUser mentions you in a postHigh
PostTaggedYou were tagged in a postUser tags you in a postHigh
PostReadyYour post is readyPost processing completedLow

Story-Related Notifications

TypeDescriptionTriggerPriority
StoryReadyYour story is readyStory processing completedLow
StoryViewedSomeone viewed your storyUser views your storyLow
StoryReactedSomeone reacted to your storyUser reacts to your storyNormal

Messaging Notifications

TypeDescriptionTriggerPriority
DirectMessageNew direct messageUser sends you a messageHigh
GroupMessageNew group messageMessage in a group you're inNormal

Follow Notifications

TypeDescriptionTriggerPriority
UserFollowedSomeone started following youUser follows your profileNormal
UserUnfollowedSomeone unfollowed youUser unfollows your profileLow

Group Notifications

TypeDescriptionTriggerPriority
GroupInviteInvited to a groupSomeone invites you to a groupHigh
GroupJoinedJoined a groupYou join a groupNormal
GroupLeftLeft a groupYou leave a groupLow
GroupPostCreatedNew post in groupPost created in a group you're inNormal
GroupRoleChangedGroup role changedYour role in a group changedNormal

Event Notifications

TypeDescriptionTriggerPriority
EventInviteInvited to an eventSomeone invites you to an eventHigh
EventReminderEvent reminderEvent is coming upNormal
EventUpdatedEvent updatedEvent details changedNormal
EventCancelledEvent cancelledEvent was cancelledHigh

Birthday & Anniversary

TypeDescriptionTriggerPriority
BirthdayYour birthday reminderYour birthdayNormal
FriendBirthdayFriend's birthdayFriend's birthdayNormal
AnniversaryAnniversary reminderRelationship anniversaryNormal

System Notifications

TypeDescriptionTriggerPriority
SystemAnnouncementSystem announcementImportant platform updatesHigh
SecurityAlertSecurity notificationSecurity-related eventsUrgent
AccountUpdatedAccount updatedAccount settings changedNormal

Achievement Notifications

TypeDescriptionTriggerPriority
FirstPostFirst post milestoneYou create your first postNormal
PopularPostPopular postYour post becomes popularNormal
MilestoneReachedMilestone reachedYou reach a milestoneNormal

General

TypeDescriptionTriggerPriority
GeneralGeneral notificationCustom notificationsNormal

How Notifications Work

Notification Lifecycle

  1. Creation: Notification is created when a domain event occurs (e.g., post liked, friend request sent)
  2. Storage: Saved to MongoDB for persistence and history
  3. Queue: Published to message queue (RabbitMQ) for processing
  4. Processing: WebSocketWorker processes the notification
  5. Delivery: Sent via SignalR WebSocket to connected clients in real-time
  6. 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, Archived
  • type (optional) - Filter by type: PostLiked, FriendRequest, etc.
  • priority (optional) - Filter by priority: Low, Normal, High, Urgent
  • includeExpired (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 statistics
  • toDate (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:

  1. Domain Event: When an action occurs (e.g., post liked), a domain event is raised
  2. Event Handler: NotificationCreatedDomainEventHandler processes the event
  3. Message Queue: Notification is published to RabbitMQ queue
  4. WebSocketWorker: Background worker consumes from queue
  5. SignalR Hub: Worker sends notification via SignalR to connected clients
  6. 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

EventDescriptionPayload
ReceiveNotificationNew notification received{ notification: {...} }
NotificationReadNotification marked as read{ notificationId: "..." }
NotificationCountUpdatedUnread count changed{ count: 5 }
NotificationDeletedNotification deleted{ notificationId: "..." }
NotificationBatchReadMultiple 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/expo after 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

  1. Domain Layer (Domain/Modules/Notification)

    • Notification entity with business logic
    • Notification value objects (Type, Status, Priority)
    • Domain events for notification creation
  2. Application Layer (Application/Modules/Notification)

    • Commands: Create, Update, Delete notifications
    • Queries: Get notifications, stats, counts
    • Event handlers for automatic notification creation
  3. Infrastructure Layer

    • MongoDB Repository: Persistent storage
    • Redis Cache: Unread counts and caching
    • RabbitMQ: Message queue for async processing
    • SignalR Hub: Real-time WebSocket delivery
  4. 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

  1. Regular Check-ins: Review notifications regularly to stay updated
  2. Mark as Read: Keep your notification list organized
  3. Configure Preferences: Adjust settings to receive only relevant notifications
  4. Use Quiet Hours: Enable quiet hours to avoid notifications during sleep
  5. Archive Old Notifications: Archive notifications you want to keep but don't need to see
  6. Filter by Priority: Focus on high-priority notifications first
  7. Use Action URLs: Click notifications to navigate directly to related content

For Developers

  1. Real-time Updates: Always use WebSocket for instant notification delivery
  2. Batch Operations: Use batch read operations for better performance
  3. Filtering: Implement client-side filtering for better UX
  4. Pagination: Always use pagination for notification lists
  5. Error Handling: Handle WebSocket disconnections gracefully
  6. Polling Fallback: Implement polling as fallback if WebSocket fails
  7. Optimistic Updates: Update UI optimistically before server confirmation
  8. Cache Unread Count: Cache unread count to reduce API calls
  9. Debounce Updates: Debounce rapid status updates to reduce server load
  10. Handle Expiration: Check expiresAt before 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.