A secure, lightweight, and scalable Firebase Cloud Messaging (FCM) gateway built with Node.js, using MySQL for subscriber management, Redis for message queuing, and Winston for structured logging.
- ✅ Token-based authentication for all endpoints
- ✅ Send to one or all subscribers
- ✅ FCM push messaging with auto-removal of invalid tokens
- ✅ MySQL: persistent subscriber store
- ✅ Redis: batch queuing of messages (1,000-token chunks)
- ✅ Worker daemon that processes queued pushes
- ✅ Winston logging (colorized console + file logging)
- ✅ .env configuration
- ✅ PM2 & Docker support
- ✅ Heartbeat & stats endpoints
- Node.js
- Express
- Firebase Admin SDK
- MySQL
- Redis
- Winston Logger
- dotenv
- helmet
- PM2
- Docker
git clone https://github.com/yourname/fcmGateway.git
cd fcmGatewaynpm installDownload the serviceAccountKey.json from Firebase Console and place it in the root folder.
PORT=3000
API_KEY=yourSecretApiKey123
# MySQL
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=fcm_user
DB_PASS=fcm_pass
DB_NAME=fcm_gateway
# Redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_USERNAME=default
REDIS_PASSWORD=supersecret
REDIS_CHANNEL=fcm_push_queueRegisters a device for push notifications.
{
"deviceToken": "fcm_token_here",
"clientId": "unique_device_id"
}Removes a device token from the database.
{
"deviceToken": "fcm_token_here"
}Sends a push message to a single device.
{
"deviceToken": "fcm_token_here",
"clientId": "device-12345",
"data": {
"id": 85200258,
"eventTime": "2025-05-19 12:28:15",
"title": "Message content test 3",
"body": "A 4.4 magnitude earthquake struck the volcanic area around Naples as part of a 'major' quake swarm on Tuesday, sparking fear but no immediate reports of damage. The tremor hit the Campi Flegrei area in southern Italy at 12:07 pm, at a depth of three kilometres, according to Italy's National Institute of Geophysics and Volcanology.<br><br>Underground activity<br><br><br><a href=\"https://map.crisisinfo.eu\">Jump link</a>",
"event": "earthquake",
"lat": 40.8270141,
"lon": 14.1195161,
"categoryCode": "EQ",
"messageLevel": 3
}
}🛡 Requires: x-api-key header
Queues a broadcast message to all subscribers (in 1,000-token chunks) via Redis.
{
"data": {
"id": 85200258,
"eventTime": "2025-05-19 12:28:15",
"title": "Message content test 3",
"body": "A 4.4 magnitude earthquake struck the volcanic area around Naples as part of a 'major' quake swarm on Tuesday, sparking fear but no immediate reports of damage. The tremor hit the Campi Flegrei area in southern Italy at 12:07 pm, at a depth of three kilometres, according to Italy's National Institute of Geophysics and Volcanology.<br><br>Underground activity<br><br><br><a href=\"https://map.crisisinfo.eu\">Jump link</a>",
"event": "earthquake",
"lat": 40.8270141,
"lon": 14.1195161,
"categoryCode": "EQ",
"messageLevel": 3
}
}Returns basic service status and current timestamp.
Returns current subscriber count from the database.
The worker.js script runs independently and continuously listens to the Redis queue to process push messages.
Start manually:
node worker.jsOr via PM2:
pm2 start ecosystem.config.js| Column | Type | Description |
|---|---|---|
| id | INT (PK) | Auto increment |
| device_token | VARCHAR(255) | Firebase device token |
| client_id | VARCHAR(64) | Unique device identifier |
| subscribed_at | DATETIME | Subscription timestamp |
| last_seen | DATETIME | Last active ping/renewal |
Start both app and worker with:
pm2 start ecosystem.config.js
pm2 save
pm2 startupdocker-compose up -d --buildfcm-api: Express-based REST APIfcm-worker: Background worker for Redis queueredis: In-memory message queue
pm2 list
pm2 logs fcmGateway
pm2 logs fcmWorkerMIT – free to use, modify, and share.
Made with ☕ and ❤️ by Zsolt Boszormenyi · Contact: hunnomad@gmail.com