Software: Apache/2.4.41 (Ubuntu). PHP/8.0.30 uname -a: Linux apirnd 5.4.0-204-generic #224-Ubuntu SMP Thu Dec 5 13:38:28 UTC 2024 x86_64 uid=33(www-data) gid=33(www-data) groups=33(www-data) Safe-mode: OFF (not secure) /var/www/html/sync/src/firebase/ drwxr-xr-x | |
| Viewing file: Select action/file-type: var admin = require("firebase-admin");
const { MongoClient } = require("mongodb");
const { connectToMongo } = require('../client');
const { getNextSequence } = require("../vendorSequence");
var serviceAccount = require("../../serviceAccount.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
const INVALID_CODES = [
"messaging/registration-token-not-registered",
"messaging/invalid-registration-token",
"messaging/unregistered",
"messaging/mismatch-sender-id"
];
// Errors that mean a retry *may* succeed later
const RETRYABLE_CODES = [
"messaging/internal-error",
"messaging/server-unavailable",
"messaging/unknown-error"
];
async function getToken(vendor_id) {
// const MONGO_URI = process.env.MONGO_URI;
// const DB_NAME = process.env.MONGO_DB_NAME;
// const client = new MongoClient(MONGO_URI);
// await client.connect();
// const db = client.db(DB_NAME);
const db = await connectToMongo();
try {
const data = await db.collection("DeviceToken").findOne({"vendor_id":vendor_id.toString()},{"tokens":1});
return data;
} catch(err) {
console.log(err.message);
}
}
async function removeToken(vendor_id,failedTokens) {
try {
console.log(failedTokens);
if (!failedTokens || failedTokens.length === 0) return;
const db = await connectToMongo();
const result = await db.collection('DeviceToken').updateOne(
{ "vendor_id": vendor_id.toString()},
{ $pull: { tokens: { $in: failedTokens } } }
);
// const db = await connectToMongo();
// const data = await DeviceToken.updateOne(
// { "vendor_id": vendor_id.toString()},
// {$pull: { "tokens": { $in: tokens }}}
// );
return result;
} catch(err) {
console.log(err.message);
}
}
async function sendFCMMessage(vendorId, tokens, messagePayload, retryAttempt = 0) {
try {
var message = {
// android: {
// priority: 'high',
// collapseKey: 'msg_' + Date.now() // Unique key
// },
// notification: {
// title: "Data Changed",
// body: "NEW DATA ADDED"
// },
android: {
priority: 'high'
},
data: {
data: JSON.stringify(messagePayload)
},
tokens: tokens
};
const response = await admin.messaging().sendEachForMulticast(message);
const invalidTokens = [];
const retryTokens = [];
response.responses.forEach((res, idx) => {
if (!res.success) {
const code = res.error?.code;
if (INVALID_CODES.includes(code)) {
invalidTokens.push(tokens[idx]);
} else if (RETRYABLE_CODES.includes(code)) {
retryTokens.push(tokens[idx]);
}
}
});
// Remove permanently invalid tokens
if (invalidTokens.length > 0) {
await removeToken(vendorId, invalidTokens);
// console.log(`[${vendorId}] Removed invalid tokens:`, invalidTokens.length);
}
// Retry transient failures (max 3 times)
if (retryTokens.length > 0 && retryAttempt < 3) {
const delay = (retryAttempt + 1) * 2000; // exponential backoff: 2s, 4s, 6s
// console.log(
// `[${vendorId}] Retrying ${retryTokens.length} tokens (attempt ${retryAttempt + 1}) after ${delay}ms`
// );
await new Promise((r) => setTimeout(r, delay));
await sendFCMMessage(vendorId, retryTokens, messagePayload, retryAttempt + 1);
}
// console.log(`[${vendorId}] FCM result: ${response.successCount} success, ${response.failureCount} failed`);
return "done";
} catch (err) {
console.error(`[${vendorId}] FCM send error:`, err.message);
if (retryAttempt < 3 && /unavailable|internal/i.test(err.message)) {
const delay = (retryAttempt + 1) * 2000;
// console.log(`[${vendorId}] Retrying all tokens (attempt ${retryAttempt + 1}) after ${delay}ms`);
await new Promise((r) => setTimeout(r, delay));
await sendFCMMessage(vendorId, tokens, messagePayload, retryAttempt + 1);
}else{
return "error";
}
}
}
// getToken(88000001);
async function sendMessage(payload) {
try {
var vendor_id = payload.vendor_id;
var vendor=await getToken(vendor_id);
if(!vendor || !vendor.tokens || vendor.tokens.length==0){
return "no token";
}
var seq = await getNextSequence(vendor_id);
delete payload.vendor_id;
payload.sequence = seq;
payload.type = "sync";
// console.log(payload);
var res=await sendFCMMessage(vendor_id, vendor.tokens, payload, 0);
return res;
// const response =await admin.messaging().sendEachForMulticast(message);
// .then(async(response) => {
// if (response.failureCount > 0) {
// const failedTokens = [];
// response.responses.forEach((resp, idx) => {
// if (!resp.success) {
// // console.log('Failure sending notification to', vendor.tokens[idx], resp.error);
// // console.log(idx);
// failedTokens.push(vendor.tokens[idx]);
// }
// });
// console.log('List of tokens that caused failures: ' + response.failureCount);
// }
// console.log(response.successCount + ' messages were sent successfully');
// }).catch((error)=>{
// console.log(error);
// });
// return "done";
}
catch (error) {
console.log("error",error.message);
return "error";
}
}
module.exports = { sendMessage }; |
:: Command execute :: | |
--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0216 ]-- |