79 lines
2.6 KiB
JavaScript
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);
|
|
}
|
|
};
|