Skip to content

Commit 6d5d12c

Browse files
mohitpubnubMohit Tejanipubnub-release-bot
authored
fix FCM Push notification payload structure (#492)
* fix FCM Push notification payload structure difference from firebase recommanded way * fix import and ts error for push payload * update package-lock.json for basic-ftp version upgrade * refactor the push_payload types as per review comment * updated types for push_payload builder * update FCM builder.toObject() for silent notification to add fields in `data` key. * PubNub SDK v10.2.8 release. --------- Co-authored-by: Mohit Tejani <mohit.tejani@Mohits-MacBook-Pro.local> Co-authored-by: PubNub Release Bot <120067856+pubnub-release-bot@users.noreply.github.com>
1 parent 2d58c9a commit 6d5d12c

13 files changed

Lines changed: 700 additions & 195 deletions

File tree

.pubnub.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
---
22
changelog:
3+
- date: 2026-03-10
4+
version: v10.2.8
5+
changes:
6+
- type: bug
7+
text: "Updated push notification payload builder utility method to generate fcm payload as per updated specification."
38
- date: 2026-02-11
49
version: v10.2.7
510
changes:
@@ -1389,7 +1394,7 @@ supported-platforms:
13891394
- 'Ubuntu 14.04 and up'
13901395
- 'Windows 7 and up'
13911396
version: 'Pubnub Javascript for Node'
1392-
version: '10.2.7'
1397+
version: '10.2.8'
13931398
sdks:
13941399
- full-name: PubNub Javascript SDK
13951400
short-name: Javascript
@@ -1405,7 +1410,7 @@ sdks:
14051410
- distribution-type: source
14061411
distribution-repository: GitHub release
14071412
package-name: pubnub.js
1408-
location: https://github.com/pubnub/javascript/archive/refs/tags/v10.2.7.zip
1413+
location: https://github.com/pubnub/javascript/archive/refs/tags/v10.2.8.zip
14091414
requires:
14101415
- name: 'agentkeepalive'
14111416
min-version: '3.5.2'
@@ -2076,7 +2081,7 @@ sdks:
20762081
- distribution-type: library
20772082
distribution-repository: GitHub release
20782083
package-name: pubnub.js
2079-
location: https://github.com/pubnub/javascript/releases/download/v10.2.7/pubnub.10.2.7.js
2084+
location: https://github.com/pubnub/javascript/releases/download/v10.2.8/pubnub.10.2.8.js
20802085
requires:
20812086
- name: 'agentkeepalive'
20822087
min-version: '3.5.2'

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## v10.2.8
2+
March 10 2026
3+
4+
#### Fixed
5+
- Updated push notification payload builder utility method to generate fcm payload as per updated specification.
6+
17
## v10.2.7
28
February 11 2026
39

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ Watch [Getting Started with PubNub JS SDK](https://app.dashcam.io/replay/64ee0d2
2727
npm install pubnub
2828
```
2929
* or download one of our builds from our CDN:
30-
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.7.js
31-
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.7.min.js
30+
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.8.js
31+
* https://cdn.pubnub.com/sdk/javascript/pubnub.10.2.8.min.js
3232
3333
2. Configure your keys:
3434

dist/web/pubnub.js

Lines changed: 89 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5438,7 +5438,7 @@
54385438
return base.PubNubFile;
54395439
},
54405440
get version() {
5441-
return '10.2.7';
5441+
return '10.2.8';
54425442
},
54435443
getVersion() {
54445444
return this.version;
@@ -7555,11 +7555,6 @@
75557555
}
75567556
}
75577557

7558-
// --------------------------------------------------------
7559-
// ------------------------ Types -------------------------
7560-
// --------------------------------------------------------
7561-
// region Types
7562-
// endregion
75637558
// endregion
75647559
/**
75657560
* Base notification payload object.
@@ -7897,6 +7892,15 @@
78977892
get data() {
78987893
return this.payload.data;
78997894
}
7895+
/**
7896+
* Retrieve Android notification payload and initialize required structure.
7897+
*
7898+
* @returns Android specific notification payload.
7899+
*/
7900+
get androidNotification() {
7901+
var _c;
7902+
return (_c = this.payload.android) === null || _c === void 0 ? void 0 : _c.notification;
7903+
}
79007904
/**
79017905
* Notification title.
79027906
*
@@ -7914,6 +7918,7 @@
79147918
if (!value || !value.length)
79157919
return;
79167920
this.payload.notification.title = value;
7921+
this.androidNotification.title = value;
79177922
this._title = value;
79187923
}
79197924
/**
@@ -7933,8 +7938,28 @@
79337938
if (!value || !value.length)
79347939
return;
79357940
this.payload.notification.body = value;
7941+
this.androidNotification.body = value;
79367942
this._body = value;
79377943
}
7944+
/**
7945+
* Retrieve unread notifications number.
7946+
*
7947+
* @returns Number of unread notifications which should be shown on application badge.
7948+
*/
7949+
get badge() {
7950+
return this._badge;
7951+
}
7952+
/**
7953+
* Update application badge number.
7954+
*
7955+
* @param value - Number which should be shown in application badge upon receiving notification.
7956+
*/
7957+
set badge(value) {
7958+
if (value === undefined || value === null)
7959+
return;
7960+
this.androidNotification.notification_count = value;
7961+
this._badge = value;
7962+
}
79387963
/**
79397964
* Retrieve notification sound file.
79407965
*
@@ -7951,7 +7976,7 @@
79517976
set sound(value) {
79527977
if (!value || !value.length)
79537978
return;
7954-
this.payload.notification.sound = value;
7979+
this.androidNotification.sound = value;
79557980
this._sound = value;
79567981
}
79577982
/**
@@ -7965,12 +7990,12 @@
79657990
/**
79667991
* Update notification icon.
79677992
*
7968-
* @param value - Name of the icon file which should be shown on notification.
7993+
* @param value - Name of the icon file set for `android.notification.icon`.
79697994
*/
79707995
set icon(value) {
79717996
if (!value || !value.length)
79727997
return;
7973-
this.payload.notification.icon = value;
7998+
this.androidNotification.icon = value;
79747999
this._icon = value;
79758000
}
79768001
/**
@@ -7984,12 +8009,12 @@
79848009
/**
79858010
* Update notifications grouping tag.
79868011
*
7987-
* @param value - String which will be used to group similar notifications in notification center.
8012+
* @param value - String set for `android.notification.tag` to group similar notifications.
79888013
*/
79898014
set tag(value) {
79908015
if (!value || !value.length)
79918016
return;
7992-
this.payload.notification.tag = value;
8017+
this.androidNotification.tag = value;
79938018
this._tag = value;
79948019
}
79958020
/**
@@ -8010,6 +8035,7 @@
80108035
setDefaultPayloadStructure() {
80118036
this.payload.notification = {};
80128037
this.payload.data = {};
8038+
this.payload.android = { notification: {} };
80138039
}
80148040
/**
80158041
* Translate data object into PubNub push notification payload object.
@@ -8019,22 +8045,60 @@
80198045
* @returns Preformatted push notification payload.
80208046
*/
80218047
toObject() {
8022-
let data = Object.assign({}, this.payload.data);
8023-
let notification = null;
8048+
var _c, _e;
80248049
const payload = {};
8025-
// Check whether additional data has been passed outside 'data' object and put it into it if required.
8026-
if (Object.keys(this.payload).length > 2) {
8027-
const _a = this.payload, additionalData = __rest(_a, ["notification", "data"]);
8028-
data = Object.assign(Object.assign({}, data), additionalData);
8050+
const notification = Object.assign({}, this.payload.notification);
8051+
const android = Object.assign({}, this.payload.android);
8052+
const androidNotification = Object.assign({}, ((_c = android.notification) !== null && _c !== void 0 ? _c : {}));
8053+
// Strip title/body from android.notification — they belong in top-level notification (or data for silent).
8054+
const androidSpecificFields = __rest(androidNotification, ["title", "body"]);
8055+
if (this._isSilent) {
8056+
// For silent (data-only) notifications, strip all `notification` fields
8057+
// (both root and android) and move everything into the root `data` object.
8058+
const data = {};
8059+
if (this._title)
8060+
data.title = this._title;
8061+
if (this._body)
8062+
data.body = this._body;
8063+
// Merge android-specific notification fields (sound, icon, tag, etc.) into data.
8064+
for (const [key, value] of Object.entries(androidSpecificFields)) {
8065+
if (value !== undefined && value !== null)
8066+
data[key] = String(value);
8067+
}
8068+
// Merge any existing user-provided custom data.
8069+
if (this.payload.data)
8070+
Object.assign(data, this.payload.data);
8071+
if (Object.keys(data).length)
8072+
payload.data = data;
8073+
// Exclude `notification` entirely from android — only keep non-notification android fields.
8074+
delete android.notification;
8075+
if (Object.keys(android).length) {
8076+
payload.android = android;
8077+
}
80298078
}
8030-
if (this._isSilent)
8031-
data.notification = this.payload.notification;
8032-
else
8033-
notification = this.payload.notification;
8034-
if (Object.keys(data).length)
8035-
payload.data = data;
8036-
if (notification && Object.keys(notification).length)
8037-
payload.notification = notification;
8079+
else {
8080+
if (Object.keys(notification).length)
8081+
payload.notification = notification;
8082+
// Include top-level data if present.
8083+
if (this.payload.data && Object.keys(this.payload.data).length)
8084+
payload.data = Object.assign({}, this.payload.data);
8085+
// android.notification should only contain android-specific fields (sound, icon, tag, etc.).
8086+
if (Object.keys(androidSpecificFields).length) {
8087+
const androidWithoutNotification = __rest(android, ["notification"]);
8088+
payload.android = Object.assign(Object.assign({}, androidWithoutNotification), { notification: androidSpecificFields });
8089+
}
8090+
else {
8091+
const androidWithoutNotification = __rest(android, ["notification"]);
8092+
if (Object.keys(androidWithoutNotification).length) {
8093+
payload.android = androidWithoutNotification;
8094+
}
8095+
}
8096+
}
8097+
// Preserve other top-level FCM fields (apns, webpush, fcm_options, etc.).
8098+
const _f = this.payload, otherFields = __rest(_f, ["notification", "android", "data", "pn_exceptions"]);
8099+
Object.assign(payload, otherFields);
8100+
if ((_e = this.payload.pn_exceptions) === null || _e === void 0 ? void 0 : _e.length)
8101+
payload.pn_exceptions = this.payload.pn_exceptions;
80388102
return Object.keys(payload).length ? payload : null;
80398103
}
80408104
}

dist/web/pubnub.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/core/components/configuration.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ const makeConfiguration = (base, setupCryptoModule) => {
168168
return base.PubNubFile;
169169
},
170170
get version() {
171-
return '10.2.7';
171+
return '10.2.8';
172172
},
173173
getVersion() {
174174
return this.version;

0 commit comments

Comments
 (0)