使用fcm节点模块在nodejs中发送推送通知

时间:2017-07-26 03:25:38

标签: node.js push-notification notifications

我想在设备ID上发送推送通知,如何在该设备上发送通知。

2 个答案:

答案 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)

你可以使用nodejs包node-gcm 如需更多信息,请查看此链接,了解更多信息并解决问题。

this question

node package1