Skip to content

Commit 609e432

Browse files
committed
* Adds backwards compatibility with old GCM payload.
* Uses FCM if firebaseServiceAccount key is present in config.
1 parent 2f116ec commit 609e432

File tree

2 files changed

+59
-12
lines changed

2 files changed

+59
-12
lines changed

src/FCM.js

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { randomString } from './PushAdapterUtils';
88

99
const LOG_PREFIX = 'parse-server-push-adapter FCM';
1010
const FCMRegistrationTokensMax = 500;
11+
const FCMTimeToLiveMax = 4 * 7 * 24 * 60 * 60; // FCM allows a max of 4 weeks
1112

1213
export default function FCM(args) {
1314
if (typeof args !== 'object' || !args.firebaseServiceAccount) {
@@ -40,7 +41,6 @@ FCM.prototype.send = function(data, devices) {
4041
return;
4142
}
4243

43-
4444
// We can only have 500 recepients per send, so we need to slice devices to
4545
// chunk if necessary
4646
const slices = sliceDevices(devices, FCM.FCMRegistrationTokensMax);
@@ -60,7 +60,7 @@ FCM.prototype.send = function(data, devices) {
6060
const length = deviceTokens.length;
6161
log.info(LOG_PREFIX, `sending push to ${length} devices`);
6262

63-
return this.sender.sendEachForMulticast(fcmPayload.payload.data)
63+
return this.sender.sendEachForMulticast(fcmPayload.data)
6464
.then((response) => {
6565
const promises = [];
6666
const failedTokens = [];
@@ -101,21 +101,59 @@ FCM.prototype.send = function(data, devices) {
101101
* Generate the fcm payload from the data we get from api request.
102102
* @param {Object} requestData The request body
103103
* @param {String} pushId A random string
104-
* @param {Number} timeStamp A number whose format is the Unix Epoch
104+
* @param {Number} timeStamp A number in milliseconds since the Unix Epoch
105105
* @returns {Object} A payload for FCM
106106
*/
107107
function generateFCMPayload(requestData, pushId, timeStamp, deviceTokens) {
108108
delete requestData['where'];
109-
requestData.tokens = deviceTokens;
110-
const payload = {}
111109

112-
payload.payload = {
113-
data: requestData,
114-
push_id: pushId,
115-
time: new Date(timeStamp).toISOString()
110+
const payloadToUse = {
111+
data: {},
112+
push_id: pushId,
113+
time: new Date(timeStamp).toISOString()
114+
};
115+
116+
// Use rawPayload instead of the GCM implementation if it exists
117+
if (requestData.hasOwnProperty('rawPayload')) {
118+
payloadToUse.data = {
119+
...requestData.rawPayload,
120+
tokens: deviceTokens
121+
};
122+
} else {
123+
// Android payload according to GCM implementation
124+
const androidPayload = {
125+
android: {
126+
priority: 'high'
127+
},
128+
tokens: deviceTokens
129+
};
130+
131+
if (requestData.hasOwnProperty('notification')) {
132+
androidPayload.notification = requestData.notification;
133+
}
134+
135+
if (requestData.hasOwnProperty('data')) {
136+
androidPayload.data = requestData.data;
137+
}
138+
139+
if (requestData['expiration_time']) {
140+
const expirationTime = requestData['expiration_time'];
141+
// Convert to seconds
142+
let timeToLive = Math.floor((expirationTime - timeStamp) / 1000);
143+
if (timeToLive < 0) {
144+
timeToLive = 0;
145+
}
146+
if (timeToLive >= FCMTimeToLiveMax) {
147+
timeToLive = FCMTimeToLiveMax;
148+
}
149+
150+
androidPayload.android.ttl = timeToLive;
151+
}
152+
153+
payloadToUse.data = androidPayload;
116154
}
117155

118-
return payload;
156+
return payloadToUse;
119157
}
120158

121159
/**
@@ -132,7 +170,6 @@ function sliceDevices(devices, chunkSize) {
132170
return chunkDevices;
133171
}
134172

135-
136173
/**
137174
* Creates an errorPromise for return.
138175
*

src/ParsePushAdapter.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,19 @@ export default class ParsePushAdapter {
3131
case 'ios':
3232
case 'tvos':
3333
case 'osx':
34+
if (pushConfig[pushType].hasOwnProperty('firebaseServiceAccount')) {
35+
this.senderMap[pushType] = new FCM(pushConfig[pushType]);
36+
} else {
37+
this.senderMap[pushType] = new APNS(pushConfig[pushType]);
38+
}
39+
break;
3440
case 'android':
3541
case 'fcm':
36-
this.senderMap[pushType] = new FCM(pushConfig[pushType]);
42+
if (pushConfig[pushType].hasOwnProperty('firebaseServiceAccount')) {
43+
this.senderMap[pushType] = new FCM(pushConfig[pushType]);
44+
} else {
45+
this.senderMap[pushType] = new GCM(pushConfig[pushType]);
46+
}
3747
break;
3848
}
3949
}

0 commit comments

Comments
 (0)