【问题标题】:Send push notifications in nodejs using fcm node module使用 fcm 节点模块在 nodejs 中发送推送通知
【发布时间】:2018-01-01 04:24:24
【问题描述】:

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

【问题讨论】:

标签: node.js push-notification notifications


【解决方案1】:

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

node package1

node package2

【讨论】:

    【解决方案2】:

    我使用 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" 
                     }] 
         }
    

    【讨论】:

      猜你喜欢
      • 2017-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-17
      • 1970-01-01
      • 2022-08-22
      • 2020-10-24
      • 1970-01-01
      相关资源
      最近更新 更多