FCM Integration
🎯 Overview
Firebase Cloud Messaging (FCM) integration enables DashClicks to send push notifications to web browsers and mobile devices. The system manages device tokens, sends multicast notifications, and tracks notification delivery status and read receipts.
Provider: Google Firebase (https://firebase.google.com/docs/cloud-messaging)
API Version: Firebase Admin SDK v11+
Integration Type: Server-side SDK with HTTP/2 push protocol
📁 Directory Structure
Documentation Structure:
fcm/
├── 📄 index.md - Integration overview and setup
├── 📄 tokens.md - Device token registration and management
├── 📄 notifications.md - Send notifications and track delivery
└── 📄 notification-management.md - List, read, and manage notifications
Source Code Location:
- Base Path:
external/Integrations/FCM/ - Utils:
Utils/send-notification.js - Controller:
Controller/fcm.js - Model:
Model/fcm.js,Model/fcm-notification.js - Routes:
Routes/fcm.js
🗄️ MongoDB Collections
📚 Detailed Schema: See Database Collections Documentation
fcm.tokens
- Purpose: Store FCM device tokens per user for push notification delivery
- Model:
shared/models/fcm-token.js - Primary Use: Map users to their registered device tokens (web, mobile)
Document Structure:
{
"_id": ObjectId,
"account_id": ObjectId,
"user_id": ObjectId, // Reference to User
"web_token": [ // Array of FCM tokens for web browsers
"fcm_token_string_1",
"fcm_token_string_2"
],
"createdAt": ISODate,
"updatedAt": ISODate
}
fcm.notifications
- Purpose: Track sent notifications and read status
- Model:
shared/models/fcm-notification.js - Primary Use: Store notification history, delivery status, and user interactions
Document Structure:
{
"_id": ObjectId,
"account": ObjectId, // Account ID
"users": [ObjectId], // Recipient user IDs
"type": "task_assigned", // Notification type
"module": "tasks", // Module that triggered notification
"message": { // FCM response + notification content
"multicast_id": 0,
"success": 2,
"failure": 0,
"title": "New Task Assigned",
"body": "You have been assigned a new task",
"data": { /* custom payload */ },
"click_action": "https://app.dashclicks.com/tasks"
},
"read_by": [ObjectId], // Users who marked as read
"removed_by": [ObjectId], // Users who dismissed notification
"metadata": { // Module-specific metadata
"activity": {},
"task": {},
"report": {},
"order": {},
"communication": {}
},
"createdAt": ISODate,
"updatedAt": ISODate
}
🔐 Authentication & Configuration
Authentication Method: Google Application Default Credentials (ADC)
Required Environment Variables:
| Variable | Description | Required |
|---|---|---|
GOOGLE_APPLICATION_CREDENTIALS | Path to Firebase service account JSON file | ✅ |
Credential Setup:
- Create Firebase project at Firebase Console
- Generate service account key (JSON file)
- Set environment variable pointing to JSON file path
- Firebase Admin SDK auto-initializes using credentials
Example Service Account JSON:
{
"type": "service_account",
"project_id": "dashclicks-project",
"private_key_id": "abc123...",
"private_key": "-----BEGIN PRIVATE KEY-----\n...",
"client_email": "firebase-adminsdk@dashclicks-project.iam.gserviceaccount.com",
"client_id": "123456789",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token"
}
🏗️ Architecture Overview
Key Responsibilities:
- Device token registration and storage
- Multicast push notification delivery
- Notification history tracking
- Read/unread status management
- Module-specific notification categorization
Communication Pattern:
- Server-to-client push via Firebase Cloud Messaging
- HTTP/2 protocol for efficient delivery
- Multicast messaging (send to multiple tokens simultaneously)
- No client polling required
Token Management:
- Web tokens stored per user (supports multiple devices)
- Tokens added to array (supports concurrent sessions)
- No automatic token cleanup (manual removal required)
🔗 Features & Capabilities
Core Features
- 📘 Device Token Management - Register and store FCM tokens per user
- 📗 Send Notifications - Multicast push notification delivery
- 📙 Notification Management - List, read, and track notifications
🔄 Integration Data Flow
Token Registration Flow
sequenceDiagram
participant Client as Web/Mobile Client
participant API as FCM Controller
participant DB as MongoDB (fcm.tokens)
participant FCM as Firebase SDK
Client->>Client: Initialize FCM SDK
Client->>Client: Request notification permission
FCM-->>Client: Generate FCM token
Client->>API: POST /v1/e/fcm/web {token}
API->>DB: Find existing tokens by user_id
alt Tokens exist
API->>DB: Add token to web_token array
else No tokens
API->>DB: Create new document with token
end
DB-->>API: Token saved
API-->>Client: Success response
Notification Sending Flow
sequenceDiagram
participant Service as Internal Service
participant API as FCM Controller
participant TokenDB as MongoDB (fcm.tokens)
participant NotifDB as MongoDB (fcm.notifications)
participant FCM as Firebase Admin SDK
participant Device as User Device
Service->>API: POST /v1/e/fcm/send {users, notification}
API->>TokenDB: Find tokens for users
TokenDB-->>API: Return token arrays
API->>API: Flatten tokens from all users
API->>FCM: sendEachForMulticast(tokens, notification)
FCM->>Device: Push notification via HTTP/2
FCM-->>API: Delivery response (success/failure counts)
API->>NotifDB: Save notification + delivery status
API-->>Service: Success response
Notification Listing Flow
sequenceDiagram
participant Client as Web Client
participant API as FCM Controller
participant DB as MongoDB (fcm.notifications)
Client->>API: GET /v1/e/fcm?page=1&limit=25
API->>DB: Find notifications for user
API->>DB: Count total notifications
API->>DB: Count unread notifications
DB-->>API: Notification list + counts
API->>API: Add is_read flag per notification
API-->>Client: JSON with data + pagination + unread_count
🔗 API Endpoints
Token Management
| Endpoint | Method | Description | Auth Required |
|---|---|---|---|
/v1/e/fcm/web | POST | Register device token | ✅ |
Notification Operations
| Endpoint | Method | Description | Auth Required |
|---|---|---|---|
/v1/e/fcm/send | POST | Send notification to users | ✅ |
/v1/e/fcm | GET | List user notifications | ✅ |
/v1/e/fcm/read | PUT | Mark notifications as read | ✅ |
🚨 Error Handling
Common Error Scenarios:
-
Missing Token:
- Returns 400 when token not provided in request body
- Message: "Token not provided. (required)"
-
Firebase Initialization Failed:
- Occurs when
GOOGLE_APPLICATION_CREDENTIALSnot set or invalid - Application fails to start
- Occurs when
-
Invalid Tokens:
- Firebase returns per-token delivery status
- Failed deliveries tracked in
failurecount - System doesn't auto-remove invalid tokens
-
No Registered Tokens:
- Notification marked as sent but no actual delivery
- Success response returned (not treated as error)
Error Response Format:
{
"success": false,
"errno": 400,
"message": "Error description"
}
📊 Monitoring & Logging
Delivery Tracking:
- Success/failure counts stored in notification document
- Per-message ID returned in
resultsarray - No automatic retry for failed deliveries
Read Status Tracking:
read_byarray tracks which users read notificationremoved_byarray tracks dismissals- Unread count calculated per query
Performance Considerations:
- Multicast messaging reduces API calls
- Maximum 500 tokens per multicast batch (Firebase limit)
- No rate limiting enforced by DashClicks layer
🔗 Related Documentation
- Firebase Cloud Messaging: FCM Documentation
- Firebase Admin SDK: Admin SDK Node.js
- Device Token Management: ./tokens.md
- Send Notifications: ./notifications.md
- Notification Management: ./notification-management.md
⚠️ Important Notes
- 🔐 Service Account Required: Must have valid Firebase service account JSON file
- 📱 Client Integration: Clients must implement FCM SDK to generate tokens
- 🔄 Token Updates: Same token can be registered multiple times (uses $addToSet)
- 📊 No Automatic Cleanup: Invalid tokens remain in database until manually removed
- 🎯 Multicast Limit: Firebase limits multicast to 500 tokens per request
- 📝 Notification History: All sent notifications stored permanently (no TTL)
- 🔔 Module-Based: Notifications categorized by module (tasks, orders, reports, etc.)
- 👥 Multi-User: Single notification can be sent to multiple users simultaneously