我想在设备ID上发送推送通知,如何在该设备上发送通知。
答案 0 :(得分:1)
我使用FCM将通知发送给用户。我使用了Mongodb,Nodejs和fcm-push节点模块。
请查看代码,希望它能为您提供帮助。
deviceModel.js:
var mongoose = require('mongoose');
var Schema = require('mongoose').Schema;
var schema = new Schema({
userId: { type: Schema.Types.ObjectId },
userType: { type: String },
deviceType: { type: String, required: true, enum: ['apn', 'gcm'] },
deviceId: { type: String, required: true },
timestamp: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Device', schema);
<强> push.js:强>
var pushModule = require('./push');
var DeviceModel = require('./DeviceModel');
var highland = require('highland');
var FCM = require('fcm-push');
var serverKey = config.get('fcmServerKey');
var fcm = new FCM(serverKey);
var _ = require('lodash');
/**
* Handle fcm push results and updates/invalidates device ids.
*
* @param {String[]} deviceIds - array of device ids used in send.
* @param {Object} fcmResponse - fcm send response.
*/
function handleFcmSendResult(deviceIds, fcmResponse) {
// fcm results
var results = fcmResponse.results;
// changes for deviceIds
var fcmUpdated = [];
var fcmDeleted = [];
// process results
for (var i = 0; i < results.length; i++) {
var oldId = deviceIds[i];
var deviceResult = results[i];
var msgId = deviceResult.message_id;
var newId = deviceResult.registration_id;
if (_.isString(msgId) && _.isString(newId)) {
// If registration_id is set, replace the original ID with the new value
fcmUpdated.push({ oldId: oldId, newId: newId });
} else {
// Otherwise, get the value of error
var e = deviceResult.error;
if (e === 'Unavailable') {
winston.warn('Push: FCM: Feedback: device unavailable: %s.', oldId);
} else if (e === 'NotRegistered' || e === 'InvalidRegistration') {
// delete invalid devices
fcmDeleted.push(oldId);
}
}
}
// apply changes, in bulk
var bulkOp = DeviceModel.collection.initializeUnorderedBulkOp();
if (fcmUpdated.length > 0) {
fcmUpdated.forEach(function (upd) {
bulkOp.find({ deviceId: upd.oldId }).update({ deviceId: upd.newId, timestamp: Date.now() });
});
// those old ids that are updated, need not be deleted
fcmDeleted = _.difference(fcmDeleted, _.map(fcmUpdated, _.property('oldId')));
}
if (fcmDeleted.length > 0) {
bulkOp.find({ deviceId: { '$in': fcmDeleted } }).remove();
}
console.log(bulkOp);
// run bulk op
bulkOp.execute();
}
/**
* Dispatch FCM push to device ids.
*
* @param {String[]} deviceIds - array of apn device ids.
* @param {String} eventName - event name.
* @param {*} eventData - event data.
*/
function sendFcm(deviceIds, eventName, eventData) {
// payload
var msgOpts = {
priority: 'high',
registration_ids: deviceIds,
data: _.set(eventData, 'eventName', eventName),
notification: eventData,
content_available: true,
mutable_content: true
};
fcm.send(msgOpts)
.then(function (response) {
console.log("SENT :",response);
// handleFcmSendResult(deviceIds, JSON.parse(response));
})
.catch(function (err) {
winston.error('Push: FCM: Error sending push.', err);
})
}
/**
* Sends push notifications to Device docs emitted from stream.
*
* @param {Stream.Readable} docStream - Stream of device docs.
* @param {String} eventName - event name.
* @param {*} eventData - event data.
*/
function streamSend(docStream, eventName, eventData) {
// stream for fcm
var fcmStream = highland();
// batch device ids from sub stream and sent to gcm
fcmStream.batch(1000).each(function (fcmIds) {
sendFcm(fcmIds, eventName, eventData);
});
// split source to sub streams
highland(docStream).each(function (doc) {
fcmStream.write(doc.deviceId);
}).done(function () {
// end sub streams when doc source is done
fcmStream.end();
});
}
/**
* Sends the event via push to all registered devices.
* @param {String} eventName - event name.
* @param {Object} eventData - event data. Can contain a "notification" object with: title, description and icon.
*/
var pushToPublic = function (eventName, eventData) {
var str = DeviceModel.find().cursor();
streamSend(str, eventName, eventData);
}
/**
* Sends the event via push to devices that are mapped to given user ids.
* @param {ObjectId[]} userIds - array of user ids.
* @param {String} eventName - event name.
* @param {Object} eventData - event data. Can contain a "notification" object with: title, description and icon.
*/
var pushToUserIds = function (userIds, eventName, eventData) {
var str = DeviceModel.find({ userId: { '$in': userIds } }).cursor();
streamSend(str, eventName, eventData);
}
// Send notification test function
var sendNotification = function () {
var payload = {
"updatedAt": "2017-06-17T06:12:42.975Z",
"message": "this is notification message",
"typeId": "591452ecad4c6b71bed61089",
"userId": "5912d45f29945b6d649f287e",
"_id": "5913f90d08b4d213f1ded021",
"isRead": false,
"isPublic": true,
// ORDER DELIVERD
"type": "order",
"title_loc_key": "title_order_delivered",
"title_loc_args": ["OrderValue"],
"body_loc_key": "body_order_delivered",
"body_loc_args": ["reminderValue"],
};
// pushToPublic("testEvent", payload);
pushToUserIds(['59562201a544614d47845eef'], "testEvent", payload)
}
sendNotification();
<强>结果:强>
SENT:{ "multicast_id":1234567891234567890,
"success":1,
"failure":0,
"canonical_ids":0,
"results":[{
"message_id": "0:12345678912345678912345678912345678"
}]
}
答案 1 :(得分:0)