api-v1/utils/fcm.js

79 lines
2.6 KiB
JavaScript

// utils/fcm.js
// This file handles Firebase Cloud Messaging (FCM) notifications.
// Note: You must provide a valid serviceAccountKey.json and install firebase-admin
// for this to strictly work. We include safety checks to prevent crashes if missing.
import admin from 'firebase-admin';
import { createRequire } from "module";
const require = createRequire(import.meta.url);
let serviceAccount = null;
try {
// Attempt to load credentials. In production, these might be env vars.
// For now, looking for a file in the project root or config folder.
serviceAccount = require("../serviceAccountKey.json");
} catch (error) {
console.warn("FCM: serviceAccountKey.json not found. Push notifications will be disabled.");
}
let isFcmInitialized = false;
if (serviceAccount) {
try {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
isFcmInitialized = true;
console.log("FCM Initialized successfully.");
} catch (error) {
console.error("Error initializing FCM:", error);
}
}
/**
* Sends a push notification to specific device tokens.
* @param {string[]} tokens - Array of FCM registration tokens
* @param {string} title - Notification title
* @param {string} body - Notification body text
* @param {object} data - Custom data payload (optional)
*/
export const sendPushNotification = async (tokens, title, body, data = {}) => {
if (!isFcmInitialized || !tokens || tokens.length === 0) {
return;
}
// Ensure tokens is an array
const validTokens = Array.isArray(tokens) ? tokens : [tokens];
const message = {
notification: {
title: title || "New Message",
body: body || "You have a new message",
},
data: {
...data,
click_action: "FLUTTER_NOTIFICATION_CLICK" // Standard for many frameworks
},
tokens: validTokens,
};
try {
const response = await admin.messaging().sendMulticast(message);
console.log(`FCM sent: ${response.successCount} successes, ${response.failureCount} failures.`);
if (response.failureCount > 0) {
const failedTokens = [];
response.responses.forEach((resp, idx) => {
if (!resp.success) {
failedTokens.push(validTokens[idx]);
// Optional: Remove invalid tokens from DB here if error code is 'messaging/registration-token-not-registered'
}
});
// console.log('Failed tokens:', failedTokens);
}
} catch (error) {
console.error("Error sending FCM notification:", error);
}
};