From ab82ff3b51c1f9064484a384ac5a09bad0f79fc1 Mon Sep 17 00:00:00 2001 From: charles-ramos Date: Fri, 10 May 2024 19:11:19 -0300 Subject: [PATCH 1/3] API Compatibility --- src/FCM.js | 309 +++++++++++++++++++++++++++-------------------------- 1 file changed, 158 insertions(+), 151 deletions(-) diff --git a/src/FCM.js b/src/FCM.js index e6bd52ec..76b4bbba 100644 --- a/src/FCM.js +++ b/src/FCM.js @@ -1,37 +1,50 @@ 'use strict'; -import Parse from 'parse'; -import log from 'npmlog'; -import { initializeApp, cert, getApps, getApp } from 'firebase-admin/app'; -import { getMessaging } from 'firebase-admin/messaging'; -import { randomString } from './PushAdapterUtils'; - -const LOG_PREFIX = 'parse-server-push-adapter FCM'; -const FCMRegistrationTokensMax = 500; -const FCMTimeToLiveMax = 4 * 7 * 24 * 60 * 60; // FCM allows a max of 4 weeks -const apnsIntegerDataKeys = [ - 'badge', - 'content-available', - 'mutable-content', - 'priority', - 'expiration_time', -]; - -export default function FCM(args, pushType) { - if (typeof args !== 'object' || !args.firebaseServiceAccount) { - throw new Parse.Error( - Parse.Error.PUSH_MISCONFIGURED, - 'FCM Configuration is invalid', - ); +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.default = FCM; + +var _parse = require('parse'); + +var _parse2 = _interopRequireDefault(_parse); + +var _npmlog = require('npmlog'); + +var _npmlog2 = _interopRequireDefault(_npmlog); + +var _app = require('firebase-admin/app'); + +var _messaging = require('firebase-admin/messaging'); + +var _PushAdapterUtils = require('./PushAdapterUtils'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var LOG_PREFIX = 'parse-server-push-adapter FCM'; +var FCMRegistrationTokensMax = 500; +var FCMTimeToLiveMax = 4 * 7 * 24 * 60 * 60; // FCM allows a max of 4 weeks +var apnsIntegerDataKeys = ['badge', 'content-available', 'mutable-content', 'priority', 'expiration_time']; + +function FCM(args, pushType) { +console.log(args) +console.log('nessa parte') +if ((typeof args === 'undefined' ? 'undefined' : _typeof(args)) !== 'object' || !args.firebaseServiceAccount) { + throw new _parse2.default.Error(_parse2.default.Error.PUSH_MISCONFIGURED, 'FCM Configuration is invalid'); } - let app; - if (getApps().length === 0) { - app = initializeApp({ credential: cert(args.firebaseServiceAccount) }); + var app = void 0; + if ((0, _app.getApps)().length === 0) { + app = (0, _app.initializeApp)({ credential: (0, _app.cert)(args.firebaseServiceAccount) }); } else { - app = getApp(); + app = (0, _app.getApp)(); } - this.sender = getMessaging(app); + this.sender = (0, _messaging.getMessaging)(app); this.pushType = pushType; // Push type is only used to remain backwards compatible with APNS and GCM } @@ -45,111 +58,84 @@ FCM.FCMRegistrationTokensMax = FCMRegistrationTokensMax; */ FCM.prototype.send = function (data, devices) { + var _this = this; + if (!data || !devices || !Array.isArray(devices)) { - log.warn(LOG_PREFIX, 'invalid push payload'); + _npmlog2.default.warn(LOG_PREFIX, 'invalid push payload'); return; } // We can only have 500 recepients per send, so we need to slice devices to // chunk if necessary - const slices = sliceDevices(devices, FCM.FCMRegistrationTokensMax); + var slices = sliceDevices(devices, FCM.FCMRegistrationTokensMax); - const sendToDeviceSlice = (deviceSlice, pushType) => { - const pushId = randomString(10); - const timestamp = Date.now(); + var sendToDeviceSlice = function sendToDeviceSlice(deviceSlice, pushType) { + var pushId = (0, _PushAdapterUtils.randomString)(10); + var timestamp = Date.now(); // Build a device map - const devicesMap = deviceSlice.reduce((memo, device) => { + var devicesMap = deviceSlice.reduce(function (memo, device) { memo[device.deviceToken] = device; return memo; }, {}); - const deviceTokens = Object.keys(devicesMap); - - const fcmPayload = generateFCMPayload( - data, - pushId, - timestamp, - deviceTokens, - pushType, - ); - const length = deviceTokens.length; - log.info(LOG_PREFIX, `sending push to ${length} devices`); - - return this.sender - .sendEachForMulticast(fcmPayload.data) - .then((response) => { - const promises = []; - const failedTokens = []; - const successfulTokens = []; - - response.responses.forEach((resp, idx) => { - if (resp.success) { - successfulTokens.push(deviceTokens[idx]); - promises.push( - createSuccessfulPromise( - deviceTokens[idx], - devicesMap[deviceTokens[idx]].deviceType, - ), - ); - } else { - failedTokens.push(deviceTokens[idx]); - promises.push( - createErrorPromise( - deviceTokens[idx], - devicesMap[deviceTokens[idx]].deviceType, - resp.error, - ), - ); - log.error( - LOG_PREFIX, - `failed to send to ${deviceTokens[idx]} with error: ${JSON.stringify(resp.error)}`, - ); - } - }); - - if (failedTokens.length) { - log.error( - LOG_PREFIX, - `tokens with failed pushes: ${JSON.stringify(failedTokens)}`, - ); + var deviceTokens = Object.keys(devicesMap); + + var fcmPayload = generateFCMPayload(data, pushId, timestamp, deviceTokens, pushType); + var length = deviceTokens.length; + _npmlog2.default.info(LOG_PREFIX, 'sending push to ' + length + ' devices'); + + return _this.sender.sendEachForMulticast(fcmPayload.data).then(function (response) { + var promises = []; + var failedTokens = []; + var successfulTokens = []; + + response.responses.forEach(function (resp, idx) { + if (resp.success) { + successfulTokens.push(deviceTokens[idx]); + promises.push(createSuccessfulPromise(deviceTokens[idx], devicesMap[deviceTokens[idx]].deviceType)); + } else { + failedTokens.push(deviceTokens[idx]); + promises.push(createErrorPromise(deviceTokens[idx], devicesMap[deviceTokens[idx]].deviceType, resp.error)); + _npmlog2.default.error(LOG_PREFIX, 'failed to send to ' + deviceTokens[idx] + ' with error: ' + JSON.stringify(resp.error)); } + }); - if (successfulTokens.length) { - log.verbose( - LOG_PREFIX, - `tokens with successful pushes: ${JSON.stringify(successfulTokens)}`, - ); - } + if (failedTokens.length) { + _npmlog2.default.error(LOG_PREFIX, 'tokens with failed pushes: ' + JSON.stringify(failedTokens)); + } - return Promise.all(promises); - }); + if (successfulTokens.length) { + _npmlog2.default.verbose(LOG_PREFIX, 'tokens with successful pushes: ' + JSON.stringify(successfulTokens)); + } + + return Promise.all(promises); + }); }; - const allPromises = Promise.all( - slices.map((slice) => sendToDeviceSlice(slice, this.pushType)), - ).catch((err) => { - log.error(LOG_PREFIX, `error sending push: ${err}`); + var allPromises = Promise.all(slices.map(function (slice) { + return sendToDeviceSlice(slice, _this.pushType); + })).catch(function (err) { + _npmlog2.default.error(LOG_PREFIX, 'error sending push: ' + err); }); return allPromises; }; function _APNSToFCMPayload(requestData) { - let coreData = requestData; + var coreData = requestData; if (requestData.hasOwnProperty('data')) { coreData = requestData.data; } - let expirationTime = - requestData['expiration_time'] || coreData['expiration_time']; - let collapseId = requestData['collapse_id'] || coreData['collapse_id']; - let pushType = requestData['push_type'] || coreData['push_type']; - let priority = requestData['priority'] || coreData['priority']; + var expirationTime = requestData['expiration_time'] || coreData['expiration_time']; + var collapseId = requestData['collapse_id'] || coreData['collapse_id']; + var pushType = requestData['push_type'] || coreData['push_type']; + var priority = requestData['priority'] || coreData['priority']; - let apnsPayload = { apns: { payload: { aps: {} } } }; - let headers = {}; + var apnsPayload = { apns: { payload: { aps: {} } } }; + var headers = {}; // Set to alert by default if not set explicitly headers['apns-push-type'] = 'alert'; @@ -172,7 +158,7 @@ function _APNSToFCMPayload(requestData) { apnsPayload.apns.headers = headers; } - for (let key in coreData) { + for (var key in coreData) { switch (key) { case 'aps': apnsPayload['apns']['payload']['aps'] = coreData.aps; @@ -190,8 +176,7 @@ function _APNSToFCMPayload(requestData) { if (!apnsPayload['apns']['payload']['aps'].hasOwnProperty('alert')) { apnsPayload['apns']['payload']['aps']['alert'] = {}; } - apnsPayload['apns']['payload']['aps']['alert']['title'] = - coreData.title; + apnsPayload['apns']['payload']['aps']['alert']['title'] = coreData.title; break; case 'badge': apnsPayload['apns']['payload']['aps']['badge'] = coreData.badge; @@ -200,20 +185,16 @@ function _APNSToFCMPayload(requestData) { apnsPayload['apns']['payload']['aps']['sound'] = coreData.sound; break; case 'content-available': - apnsPayload['apns']['payload']['aps']['content-available'] = - coreData['content-available']; + apnsPayload['apns']['payload']['aps']['content-available'] = coreData['content-available']; break; case 'mutable-content': - apnsPayload['apns']['payload']['aps']['mutable-content'] = - coreData['mutable-content']; + apnsPayload['apns']['payload']['aps']['mutable-content'] = coreData['mutable-content']; break; case 'targetContentIdentifier': - apnsPayload['apns']['payload']['aps']['target-content-id'] = - coreData.targetContentIdentifier; + apnsPayload['apns']['payload']['aps']['target-content-id'] = coreData.targetContentIdentifier; break; case 'interruptionLevel': - apnsPayload['apns']['payload']['aps']['interruption-level'] = - coreData.interruptionLevel; + apnsPayload['apns']['payload']['aps']['interruption-level'] = coreData.interruptionLevel; break; case 'category': apnsPayload['apns']['payload']['aps']['category'] = coreData.category; @@ -221,7 +202,8 @@ function _APNSToFCMPayload(requestData) { case 'threadId': apnsPayload['apns']['payload']['aps']['thread-id'] = coreData.threadId; break; - case 'expiration_time': // Exclude header-related fields as these are set above + case 'expiration_time': + // Exclude header-related fields as these are set above break; case 'collapse_id': break; @@ -238,30 +220,65 @@ function _APNSToFCMPayload(requestData) { } function _GCMToFCMPayload(requestData, timeStamp) { - const androidPayload = { + var androidPayload = { android: { - priority: 'high', - }, + priority: 'high' + } }; - if (requestData.hasOwnProperty('notification')) { - androidPayload.android.notification = requestData.notification; - } +if (requestData.hasOwnProperty('notification')) { + androidPayload.android.notification = requestData.notification; +} else if (requestData.hasOwnProperty('data')) {; + androidPayload.android.notification = {}; + if (requestData.data.title) androidPayload.android.notification['title'] = requestData.data.title; + if (requestData.data.alert) androidPayload.android.notification['body'] = requestData.data.alert; + else if (requestData.data.body) androidPayload.android.notification['body'] = requestData.data.body; +} + +if (typeof androidPayload.android.notification.body == "object") androidPayload.android.notification['body'] = JSON.stringify(androidPayload.android.notification.body) if (requestData.hasOwnProperty('data')) { // FCM gives an error on send if we have apns keys that should have integer values - for (const key of apnsIntegerDataKeys) { - if (requestData.data.hasOwnProperty(key)) { - delete requestData.data[key] + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = apnsIntegerDataKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var key = _step.value; + + if (requestData.data.hasOwnProperty(key)) { + delete requestData.data[key]; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } } - androidPayload.android.data = requestData.data; + + if (requestData.data && requestData.data.alert && typeof requestData.data.alert == "object"){ + androidPayload.android.data = { + ...requestData.data, + alert: JSON.stringify(requestData.data.alert) + } +} + else androidPayload.android.data = requestData.data; } if (requestData['expiration_time']) { - const expirationTime = requestData['expiration_time']; + var expirationTime = requestData['expiration_time']; // Convert to seconds - let timeToLive = Math.floor((expirationTime - timeStamp) / 1000); + var timeToLive = Math.floor((expirationTime - timeStamp) / 1000); if (timeToLive < 0) { timeToLive = 0; } @@ -294,10 +311,7 @@ function payloadConverter(requestData, pushType, timeStamp) { } else if (pushType === 'android') { return _GCMToFCMPayload(requestData, timeStamp); } else { - throw new Parse.Error( - Parse.Error.PUSH_MISCONFIGURED, - 'Unsupported push type, apple or android only.', - ); + throw new _parse2.default.Error(_parse2.default.Error.PUSH_MISCONFIGURED, 'Unsupported push type, apple or android only.'); } } @@ -310,26 +324,19 @@ function payloadConverter(requestData, pushType, timeStamp) { * @param {String} pushType Either apple or android * @returns {Object} A payload for FCM */ -function generateFCMPayload( - requestData, - pushId, - timeStamp, - deviceTokens, - pushType, -) { +function generateFCMPayload(requestData, pushId, timeStamp, deviceTokens, pushType) { delete requestData['where']; - const payloadToUse = { + var payloadToUse = { data: {}, push_id: pushId, - time: new Date(timeStamp).toISOString(), + time: new Date(timeStamp).toISOString() }; - const fcmPayload = payloadConverter(requestData, pushType, timeStamp); - payloadToUse.data = { - ...fcmPayload, - tokens: deviceTokens, - }; + var fcmPayload = payloadConverter(requestData, pushType, timeStamp); + payloadToUse.data = _extends({}, fcmPayload, { + tokens: deviceTokens + }); return payloadToUse; } @@ -341,7 +348,7 @@ function generateFCMPayload( * @returns {Array} An array which contains several arrays of devices with fixed chunk size */ function sliceDevices(devices, chunkSize) { - const chunkDevices = []; + var chunkDevices = []; while (devices.length > 0) { chunkDevices.push(devices.splice(0, chunkSize)); } @@ -360,9 +367,9 @@ function createErrorPromise(token, deviceType, errorMessage) { transmitted: false, device: { deviceToken: token, - deviceType: deviceType, + deviceType: deviceType }, - response: { error: errorMessage }, + response: { error: errorMessage } }); } @@ -377,8 +384,8 @@ function createSuccessfulPromise(token, deviceType) { transmitted: true, device: { deviceToken: token, - deviceType: deviceType, - }, + deviceType: deviceType + } }); } @@ -387,4 +394,4 @@ FCM.generateFCMPayload = generateFCMPayload; /* istanbul ignore else */ if (process.env.TESTING) { FCM.sliceDevices = sliceDevices; -} +} \ No newline at end of file From 96382e3ba2436acb0930c8e83216bf3cceb7c575 Mon Sep 17 00:00:00 2001 From: charles-ramos Date: Fri, 10 May 2024 19:20:13 -0300 Subject: [PATCH 2/3] API Compatibility --- src/FCM.js | 346 ++++++++++++++++++++++++++++------------------------- 1 file changed, 180 insertions(+), 166 deletions(-) diff --git a/src/FCM.js b/src/FCM.js index 76b4bbba..9b906f11 100644 --- a/src/FCM.js +++ b/src/FCM.js @@ -1,50 +1,37 @@ 'use strict'; -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -exports.default = FCM; - -var _parse = require('parse'); - -var _parse2 = _interopRequireDefault(_parse); - -var _npmlog = require('npmlog'); - -var _npmlog2 = _interopRequireDefault(_npmlog); - -var _app = require('firebase-admin/app'); - -var _messaging = require('firebase-admin/messaging'); - -var _PushAdapterUtils = require('./PushAdapterUtils'); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var LOG_PREFIX = 'parse-server-push-adapter FCM'; -var FCMRegistrationTokensMax = 500; -var FCMTimeToLiveMax = 4 * 7 * 24 * 60 * 60; // FCM allows a max of 4 weeks -var apnsIntegerDataKeys = ['badge', 'content-available', 'mutable-content', 'priority', 'expiration_time']; - -function FCM(args, pushType) { -console.log(args) -console.log('nessa parte') -if ((typeof args === 'undefined' ? 'undefined' : _typeof(args)) !== 'object' || !args.firebaseServiceAccount) { - throw new _parse2.default.Error(_parse2.default.Error.PUSH_MISCONFIGURED, 'FCM Configuration is invalid'); +import Parse from 'parse'; +import log from 'npmlog'; +import { initializeApp, cert, getApps, getApp } from 'firebase-admin/app'; +import { getMessaging } from 'firebase-admin/messaging'; +import { randomString } from './PushAdapterUtils'; + +const LOG_PREFIX = 'parse-server-push-adapter FCM'; +const FCMRegistrationTokensMax = 500; +const FCMTimeToLiveMax = 4 * 7 * 24 * 60 * 60; // FCM allows a max of 4 weeks +const apnsIntegerDataKeys = [ + 'badge', + 'content-available', + 'mutable-content', + 'priority', + 'expiration_time', +]; + +export default function FCM(args, pushType) { + if (typeof args !== 'object' || !args.firebaseServiceAccount) { + throw new Parse.Error( + Parse.Error.PUSH_MISCONFIGURED, + 'FCM Configuration is invalid', + ); } - var app = void 0; - if ((0, _app.getApps)().length === 0) { - app = (0, _app.initializeApp)({ credential: (0, _app.cert)(args.firebaseServiceAccount) }); + let app; + if (getApps().length === 0) { + app = initializeApp({ credential: cert(args.firebaseServiceAccount) }); } else { - app = (0, _app.getApp)(); + app = getApp(); } - this.sender = (0, _messaging.getMessaging)(app); + this.sender = getMessaging(app); this.pushType = pushType; // Push type is only used to remain backwards compatible with APNS and GCM } @@ -58,84 +45,111 @@ FCM.FCMRegistrationTokensMax = FCMRegistrationTokensMax; */ FCM.prototype.send = function (data, devices) { - var _this = this; - if (!data || !devices || !Array.isArray(devices)) { - _npmlog2.default.warn(LOG_PREFIX, 'invalid push payload'); + log.warn(LOG_PREFIX, 'invalid push payload'); return; } // We can only have 500 recepients per send, so we need to slice devices to // chunk if necessary - var slices = sliceDevices(devices, FCM.FCMRegistrationTokensMax); + const slices = sliceDevices(devices, FCM.FCMRegistrationTokensMax); - var sendToDeviceSlice = function sendToDeviceSlice(deviceSlice, pushType) { - var pushId = (0, _PushAdapterUtils.randomString)(10); - var timestamp = Date.now(); + const sendToDeviceSlice = (deviceSlice, pushType) => { + const pushId = randomString(10); + const timestamp = Date.now(); // Build a device map - var devicesMap = deviceSlice.reduce(function (memo, device) { + const devicesMap = deviceSlice.reduce((memo, device) => { memo[device.deviceToken] = device; return memo; }, {}); - var deviceTokens = Object.keys(devicesMap); - - var fcmPayload = generateFCMPayload(data, pushId, timestamp, deviceTokens, pushType); - var length = deviceTokens.length; - _npmlog2.default.info(LOG_PREFIX, 'sending push to ' + length + ' devices'); - - return _this.sender.sendEachForMulticast(fcmPayload.data).then(function (response) { - var promises = []; - var failedTokens = []; - var successfulTokens = []; - - response.responses.forEach(function (resp, idx) { - if (resp.success) { - successfulTokens.push(deviceTokens[idx]); - promises.push(createSuccessfulPromise(deviceTokens[idx], devicesMap[deviceTokens[idx]].deviceType)); - } else { - failedTokens.push(deviceTokens[idx]); - promises.push(createErrorPromise(deviceTokens[idx], devicesMap[deviceTokens[idx]].deviceType, resp.error)); - _npmlog2.default.error(LOG_PREFIX, 'failed to send to ' + deviceTokens[idx] + ' with error: ' + JSON.stringify(resp.error)); + const deviceTokens = Object.keys(devicesMap); + + const fcmPayload = generateFCMPayload( + data, + pushId, + timestamp, + deviceTokens, + pushType, + ); + const length = deviceTokens.length; + log.info(LOG_PREFIX, `sending push to ${length} devices`); + + return this.sender + .sendEachForMulticast(fcmPayload.data) + .then((response) => { + const promises = []; + const failedTokens = []; + const successfulTokens = []; + + response.responses.forEach((resp, idx) => { + if (resp.success) { + successfulTokens.push(deviceTokens[idx]); + promises.push( + createSuccessfulPromise( + deviceTokens[idx], + devicesMap[deviceTokens[idx]].deviceType, + ), + ); + } else { + failedTokens.push(deviceTokens[idx]); + promises.push( + createErrorPromise( + deviceTokens[idx], + devicesMap[deviceTokens[idx]].deviceType, + resp.error, + ), + ); + log.error( + LOG_PREFIX, + `failed to send to ${deviceTokens[idx]} with error: ${JSON.stringify(resp.error)}`, + ); + } + }); + + if (failedTokens.length) { + log.error( + LOG_PREFIX, + `tokens with failed pushes: ${JSON.stringify(failedTokens)}`, + ); } - }); - if (failedTokens.length) { - _npmlog2.default.error(LOG_PREFIX, 'tokens with failed pushes: ' + JSON.stringify(failedTokens)); - } - - if (successfulTokens.length) { - _npmlog2.default.verbose(LOG_PREFIX, 'tokens with successful pushes: ' + JSON.stringify(successfulTokens)); - } + if (successfulTokens.length) { + log.verbose( + LOG_PREFIX, + `tokens with successful pushes: ${JSON.stringify(successfulTokens)}`, + ); + } - return Promise.all(promises); - }); + return Promise.all(promises); + }); }; - var allPromises = Promise.all(slices.map(function (slice) { - return sendToDeviceSlice(slice, _this.pushType); - })).catch(function (err) { - _npmlog2.default.error(LOG_PREFIX, 'error sending push: ' + err); + const allPromises = Promise.all( + slices.map((slice) => sendToDeviceSlice(slice, this.pushType)), + ).catch((err) => { + log.error(LOG_PREFIX, `error sending push: ${err}`); }); return allPromises; }; function _APNSToFCMPayload(requestData) { - var coreData = requestData; + let coreData = requestData; if (requestData.hasOwnProperty('data')) { coreData = requestData.data; } - var expirationTime = requestData['expiration_time'] || coreData['expiration_time']; - var collapseId = requestData['collapse_id'] || coreData['collapse_id']; - var pushType = requestData['push_type'] || coreData['push_type']; - var priority = requestData['priority'] || coreData['priority']; + let expirationTime = + requestData['expiration_time'] || coreData['expiration_time']; + let collapseId = requestData['collapse_id'] || coreData['collapse_id']; + let pushType = requestData['push_type'] || coreData['push_type']; + let priority = requestData['priority'] || coreData['priority']; - var apnsPayload = { apns: { payload: { aps: {} } } }; - var headers = {}; + let apnsPayload = { apns: { payload: { aps: {} } } }; + let headers = {}; // Set to alert by default if not set explicitly headers['apns-push-type'] = 'alert'; @@ -158,7 +172,7 @@ function _APNSToFCMPayload(requestData) { apnsPayload.apns.headers = headers; } - for (var key in coreData) { + for (let key in coreData) { switch (key) { case 'aps': apnsPayload['apns']['payload']['aps'] = coreData.aps; @@ -176,7 +190,8 @@ function _APNSToFCMPayload(requestData) { if (!apnsPayload['apns']['payload']['aps'].hasOwnProperty('alert')) { apnsPayload['apns']['payload']['aps']['alert'] = {}; } - apnsPayload['apns']['payload']['aps']['alert']['title'] = coreData.title; + apnsPayload['apns']['payload']['aps']['alert']['title'] = + coreData.title; break; case 'badge': apnsPayload['apns']['payload']['aps']['badge'] = coreData.badge; @@ -185,16 +200,20 @@ function _APNSToFCMPayload(requestData) { apnsPayload['apns']['payload']['aps']['sound'] = coreData.sound; break; case 'content-available': - apnsPayload['apns']['payload']['aps']['content-available'] = coreData['content-available']; + apnsPayload['apns']['payload']['aps']['content-available'] = + coreData['content-available']; break; case 'mutable-content': - apnsPayload['apns']['payload']['aps']['mutable-content'] = coreData['mutable-content']; + apnsPayload['apns']['payload']['aps']['mutable-content'] = + coreData['mutable-content']; break; case 'targetContentIdentifier': - apnsPayload['apns']['payload']['aps']['target-content-id'] = coreData.targetContentIdentifier; + apnsPayload['apns']['payload']['aps']['target-content-id'] = + coreData.targetContentIdentifier; break; case 'interruptionLevel': - apnsPayload['apns']['payload']['aps']['interruption-level'] = coreData.interruptionLevel; + apnsPayload['apns']['payload']['aps']['interruption-level'] = + coreData.interruptionLevel; break; case 'category': apnsPayload['apns']['payload']['aps']['category'] = coreData.category; @@ -202,8 +221,7 @@ function _APNSToFCMPayload(requestData) { case 'threadId': apnsPayload['apns']['payload']['aps']['thread-id'] = coreData.threadId; break; - case 'expiration_time': - // Exclude header-related fields as these are set above + case 'expiration_time': // Exclude header-related fields as these are set above break; case 'collapse_id': break; @@ -220,76 +238,62 @@ function _APNSToFCMPayload(requestData) { } function _GCMToFCMPayload(requestData, timeStamp) { - var androidPayload = { + const androidPayload = { android: { - priority: 'high' - } + priority: 'high', + }, }; -if (requestData.hasOwnProperty('notification')) { - androidPayload.android.notification = requestData.notification; -} else if (requestData.hasOwnProperty('data')) {; - androidPayload.android.notification = {}; - if (requestData.data.title) androidPayload.android.notification['title'] = requestData.data.title; - if (requestData.data.alert) androidPayload.android.notification['body'] = requestData.data.alert; - else if (requestData.data.body) androidPayload.android.notification['body'] = requestData.data.body; -} - -if (typeof androidPayload.android.notification.body == "object") androidPayload.android.notification['body'] = JSON.stringify(androidPayload.android.notification.body) + if (requestData.hasOwnProperty('notification')) { + androidPayload.android.notification = requestData.notification; + } else if (requestData.hasOwnProperty('data')) { + ; + androidPayload.android.notification = {}; + if (requestData.data.title) androidPayload.android.notification['title'] = requestData.data.title; + if (requestData.data.alert) androidPayload.android.notification['body'] = requestData.data.alert; + else if (requestData.data.body) androidPayload.android.notification['body'] = requestData.data.body; + } if (requestData.hasOwnProperty('data')) { // FCM gives an error on send if we have apns keys that should have integer values - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = apnsIntegerDataKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var key = _step.value; - - if (requestData.data.hasOwnProperty(key)) { - delete requestData.data[key]; - } + for (const key of apnsIntegerDataKeys) { + if (requestData.data.hasOwnProperty(key)) { + delete requestData.data[key] } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } + } + if (requestData.data && requestData.data.alert && typeof requestData.data.alert == "object") { + androidPayload.android.data = { + ...requestData.data, + alert: JSON.stringify(requestData.data.alert) } } - - if (requestData.data && requestData.data.alert && typeof requestData.data.alert == "object"){ - androidPayload.android.data = { - ...requestData.data, - alert: JSON.stringify(requestData.data.alert) - } -} - else androidPayload.android.data = requestData.data; + else androidPayload.android.data = requestData.data; } - if (requestData['expiration_time']) { - var expirationTime = requestData['expiration_time']; - // Convert to seconds - var timeToLive = Math.floor((expirationTime - timeStamp) / 1000); - if (timeToLive < 0) { - timeToLive = 0; - } - if (timeToLive >= FCMTimeToLiveMax) { - timeToLive = FCMTimeToLiveMax; + if (requestData.data && requestData.data.alert && typeof requestData.data.alert == "object") { + androidPayload.android.data = { + ...requestData.data, + alert: JSON.stringify(requestData.data.alert) } + } + else androidPayload.android.data = requestData.data; +} - androidPayload.android.ttl = timeToLive; +if (requestData['expiration_time']) { + const expirationTime = requestData['expiration_time']; + // Convert to seconds + let timeToLive = Math.floor((expirationTime - timeStamp) / 1000); + if (timeToLive < 0) { + timeToLive = 0; } + if (timeToLive >= FCMTimeToLiveMax) { + timeToLive = FCMTimeToLiveMax; + } + + androidPayload.android.ttl = timeToLive; +} - return androidPayload; +return androidPayload; } /** @@ -311,7 +315,10 @@ function payloadConverter(requestData, pushType, timeStamp) { } else if (pushType === 'android') { return _GCMToFCMPayload(requestData, timeStamp); } else { - throw new _parse2.default.Error(_parse2.default.Error.PUSH_MISCONFIGURED, 'Unsupported push type, apple or android only.'); + throw new Parse.Error( + Parse.Error.PUSH_MISCONFIGURED, + 'Unsupported push type, apple or android only.', + ); } } @@ -324,19 +331,26 @@ function payloadConverter(requestData, pushType, timeStamp) { * @param {String} pushType Either apple or android * @returns {Object} A payload for FCM */ -function generateFCMPayload(requestData, pushId, timeStamp, deviceTokens, pushType) { +function generateFCMPayload( + requestData, + pushId, + timeStamp, + deviceTokens, + pushType, +) { delete requestData['where']; - var payloadToUse = { + const payloadToUse = { data: {}, push_id: pushId, - time: new Date(timeStamp).toISOString() + time: new Date(timeStamp).toISOString(), }; - var fcmPayload = payloadConverter(requestData, pushType, timeStamp); - payloadToUse.data = _extends({}, fcmPayload, { - tokens: deviceTokens - }); + const fcmPayload = payloadConverter(requestData, pushType, timeStamp); + payloadToUse.data = { + ...fcmPayload, + tokens: deviceTokens, + }; return payloadToUse; } @@ -348,7 +362,7 @@ function generateFCMPayload(requestData, pushId, timeStamp, deviceTokens, pushTy * @returns {Array} An array which contains several arrays of devices with fixed chunk size */ function sliceDevices(devices, chunkSize) { - var chunkDevices = []; + const chunkDevices = []; while (devices.length > 0) { chunkDevices.push(devices.splice(0, chunkSize)); } @@ -367,9 +381,9 @@ function createErrorPromise(token, deviceType, errorMessage) { transmitted: false, device: { deviceToken: token, - deviceType: deviceType + deviceType: deviceType, }, - response: { error: errorMessage } + response: { error: errorMessage }, }); } @@ -384,8 +398,8 @@ function createSuccessfulPromise(token, deviceType) { transmitted: true, device: { deviceToken: token, - deviceType: deviceType - } + deviceType: deviceType, + }, }); } @@ -394,4 +408,4 @@ FCM.generateFCMPayload = generateFCMPayload; /* istanbul ignore else */ if (process.env.TESTING) { FCM.sliceDevices = sliceDevices; -} \ No newline at end of file +} From cef65af600b87f2c2a1d7272fb97c03f1a046c57 Mon Sep 17 00:00:00 2001 From: Charles Ramos Date: Mon, 13 May 2024 14:18:23 -0300 Subject: [PATCH 3/3] API Compatibility --- src/FCM.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/FCM.js b/src/FCM.js index 9b906f11..21037b70 100644 --- a/src/FCM.js +++ b/src/FCM.js @@ -247,11 +247,16 @@ function _GCMToFCMPayload(requestData, timeStamp) { if (requestData.hasOwnProperty('notification')) { androidPayload.android.notification = requestData.notification; } else if (requestData.hasOwnProperty('data')) { - ; androidPayload.android.notification = {}; - if (requestData.data.title) androidPayload.android.notification['title'] = requestData.data.title; - if (requestData.data.alert) androidPayload.android.notification['body'] = requestData.data.alert; - else if (requestData.data.body) androidPayload.android.notification['body'] = requestData.data.body; + if (requestData.data.title) { + androidPayload.android.notification['title'] = requestData.data.title; + } + if (requestData.data.alert) { + androidPayload.android.notification['body'] = requestData.data.alert; + } + else if (requestData.data.body) { + androidPayload.android.notification['body'] = requestData.data.body; + } } if (requestData.hasOwnProperty('data')) { @@ -261,22 +266,26 @@ function _GCMToFCMPayload(requestData, timeStamp) { delete requestData.data[key] } } - if (requestData.data && requestData.data.alert && typeof requestData.data.alert == "object") { + if (requestData.data && requestData.data.alert && typeof requestData.data.alert == 'object') { androidPayload.android.data = { ...requestData.data, alert: JSON.stringify(requestData.data.alert) } } - else androidPayload.android.data = requestData.data; + else { + androidPayload.android.data = requestData.data; + } } - if (requestData.data && requestData.data.alert && typeof requestData.data.alert == "object") { + if (requestData.data && requestData.data.alert && typeof requestData.data.alert == 'object') { androidPayload.android.data = { ...requestData.data, alert: JSON.stringify(requestData.data.alert) } } - else androidPayload.android.data = requestData.data; + else { + androidPayload.android.data = requestData.data; + } } if (requestData['expiration_time']) {