Я использую пакет «fcm-node» для отправки уведомлений на определенный идентификатор устройства.
функция sendNotification выглядит следующим образом:
const FCM = require('fcm-node');
const serverKey = process.env.SERVER_KEY;
const fcm = new FCM(serverKey);
function sendNotification(registrationToken, title, body, type, key) {
const message = {
to: registrationToken,
collapse_key: key,
notification: {
title: title,
body: body,
delivery_receipt_requested: true,
sound: `ping.aiff`
},
data: {
type: type,
my_key: key,
}
};
fcm.send(message, function (err, value) {
if (err) {
console.info(err);
return false;
} else {
console.info(value);
return value;
}
});
};
module.exports = {
sendNotification
};
Функция API, которую я использую для вызова этой функции, выглядит следующим образом:
router.get('/test', async (req, res, next) => {
const promise = new Promise((resolve, reject) => {
let data = sendNotification('', 'dfsa', 'asds', 'dfas', 'afsdf');
console.info(data)
if (data == false) reject(data);
else resolve(data);
});
promise
.then((data) => { return res.status(200).send(data); })
.catch((data) => { return res.status(500).send(data) })
});
Когда я console.info "ошибка" и "значение" из sendNotification, я получаю одно из следующих:
{"multicast_id":4488027446433525506,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1652082785265643%557c6f39557c6f39"}]};
{"multicast_id":8241007545302148303,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
В случае успеха я убедился, что устройство получает уведомление.
Проблема в данных API. Это всегда «не определено», и независимо от того, успешно ли отправлено уведомление, я получаю статус 200 Ok.
В чем проблема?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы не можете ничего вернуть из обратного вызова function (err, value) {} асинхронной функции в стиле узла.
Ваша функция sendNotification() должна возвращать обещание. util.promisify() делает удобным преобразование асинхронной функции в стиле узла в асинхронную функцию, возвращающую промисы. Обратите внимание на return, это важно:
const FCM = require('fcm-node');
const serverKey = process.env.SERVER_KEY;
const fcm = new FCM(serverKey);
const { promisify } = require('util');
fcm.sendAsync = promisify(fcm.send);
function sendNotification(registrationToken, title, body, type, key) {
return fcm.sendAsync({
to: registrationToken,
collapse_key: key,
notification: {
title: title,
body: body,
delivery_receipt_requested: true,
sound: `ping.aiff`
},
data: {
type: type,
my_key: key,
}
});
}
module.exports = {
sendNotification
};
Теперь вы можете делать то, что задумали
router.get('/test', async (req, res, next) => {
try {
const data = await sendNotification('', 'dfsa', 'asds', 'dfas', 'afsdf');
return res.status(200).send(data);
} catch (err) {
return res.status(500).send(err);
}
});
Может быть, это поможет, сначала попробуйте вернуть свой ответ (обещание) в sendNotification, так как на самом деле у вас есть функция void, поэтому она всегда не определена и после в вашем маршруте
router.get('/test', async (req, res, next) => {
try {
const data = sendNotification('', 'dfsa', 'asds', 'dfas', 'afsdf');
if (data) {
return res.status(200).send(data);
}
} catch(err) {
return res.status(500).send(err);
}
});