Skip to content

Commit 95f4152

Browse files
Mohit TejaniMohit Tejani
authored andcommitted
update FCM builder.toObject() for silent notification to add fields in data key.
1 parent e4d3aa8 commit 95f4152

3 files changed

Lines changed: 40 additions & 37 deletions

File tree

lib/core/components/push_payload.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -511,27 +511,27 @@ class FCMNotificationPayload extends BaseNotificationPayload {
511511
// Strip title/body from android.notification — they belong in top-level notification (or data for silent).
512512
const { title: _t, body: _b } = androidNotification, androidSpecificFields = __rest(androidNotification, ["title", "body"]);
513513
if (this._isSilent) {
514-
// For silent notifications, send only title/body under top-level data field.
514+
// For silent (data-only) notifications, strip all `notification` fields
515+
// (both root and android) and move everything into the root `data` object.
515516
const data = {};
516517
if (this._title)
517518
data.title = this._title;
518519
if (this._body)
519520
data.body = this._body;
521+
// Merge android-specific notification fields (sound, icon, tag, etc.) into data.
522+
for (const [key, value] of Object.entries(androidSpecificFields)) {
523+
if (value !== undefined && value !== null)
524+
data[key] = String(value);
525+
}
520526
// Merge any existing user-provided custom data.
521527
if (this.payload.data)
522528
Object.assign(data, this.payload.data);
523529
if (Object.keys(data).length)
524530
payload.data = data;
525-
// Keep android-specific notification fields (sound, icon, tag) in android.notification.
526-
if (Object.keys(androidSpecificFields).length) {
527-
const { notification: _ } = android, androidWithoutNotification = __rest(android, ["notification"]);
528-
payload.android = Object.assign(Object.assign({}, androidWithoutNotification), { notification: androidSpecificFields });
529-
}
530-
else {
531-
const { notification: _ } = android, androidWithoutNotification = __rest(android, ["notification"]);
532-
if (android.data || android.collapse_key || android.priority || android.ttl) {
533-
payload.android = androidWithoutNotification;
534-
}
531+
// Exclude `notification` entirely from android — only keep non-notification android fields.
532+
delete android.notification;
533+
if (Object.keys(android).length) {
534+
payload.android = android;
535535
}
536536
}
537537
else {

src/core/components/push_payload.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -899,29 +899,27 @@ export class FCMNotificationPayload extends BaseNotificationPayload {
899899
const { title: _t, body: _b, ...androidSpecificFields } = androidNotification;
900900

901901
if (this._isSilent) {
902-
// For silent notifications, send only title/body under top-level data field.
902+
// For silent (data-only) notifications, strip all `notification` fields
903+
// (both root and android) and move everything into the root `data` object.
903904
const data: Record<string, string> = {};
904905

905906
if (this._title) data.title = this._title;
906907
if (this._body) data.body = this._body;
907908

909+
// Merge android-specific notification fields (sound, icon, tag, etc.) into data.
910+
for (const [key, value] of Object.entries(androidSpecificFields)) {
911+
if (value !== undefined && value !== null) data[key] = String(value);
912+
}
913+
908914
// Merge any existing user-provided custom data.
909915
if (this.payload.data) Object.assign(data, this.payload.data);
910916

911917
if (Object.keys(data).length) payload.data = data;
912918

913-
// Keep android-specific notification fields (sound, icon, tag) in android.notification.
914-
if (Object.keys(androidSpecificFields).length) {
915-
const { notification: _, ...androidWithoutNotification } = android;
916-
payload.android = {
917-
...androidWithoutNotification,
918-
notification: androidSpecificFields as FCMAndroidNotification,
919-
};
920-
} else {
921-
const { notification: _, ...androidWithoutNotification } = android;
922-
if (android.data || android.collapse_key || android.priority || android.ttl) {
923-
payload.android = androidWithoutNotification;
924-
}
919+
// Exclude `notification` entirely from android — only keep non-notification android fields.
920+
delete android.notification;
921+
if (Object.keys(android).length) {
922+
payload.android = android;
925923
}
926924
} else {
927925
if (Object.keys(notification).length) payload.notification = notification;

test/unit/notifications_payload.test.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,7 @@ describe('#notifications helper', () => {
221221
data: {
222222
title: expectedTitle,
223223
body: expectedBody,
224-
},
225-
android: {
226-
notification: { sound: expectedSound },
224+
sound: expectedSound,
227225
},
228226
},
229227
};
@@ -426,17 +424,26 @@ describe('#notifications helper', () => {
426424
assert(platformPayloadStorage.android.notification);
427425
});
428426

429-
it("should set notification 'title' and 'body' with constructor", () => {
427+
428+
it("should set title and body in top-level notification and badge as notification_count in android.notification", () => {
430429
let expectedTitle = PubNub.generateUUID();
431430
let expectedBody = PubNub.generateUUID();
432431

433432
let builder = new FCMNotificationPayload(platformPayloadStorage, expectedTitle, expectedBody);
433+
builder.badge = 10;
434+
const payload = builder.toObject();
434435

435-
assert(builder);
436-
assert.equal(platformPayloadStorage.notification.title, expectedTitle);
437-
assert.equal(platformPayloadStorage.notification.body, expectedBody);
438-
assert.equal(platformPayloadStorage.android.notification.title, expectedTitle);
439-
assert.equal(platformPayloadStorage.android.notification.body, expectedBody);
436+
assert(payload);
437+
// title and body should be in top-level notification
438+
assert.equal(payload.notification!.title, expectedTitle);
439+
assert.equal(payload.notification!.body, expectedBody);
440+
// title and body should not be duplicated in android.notification
441+
assert(!payload.android?.notification?.title);
442+
assert(!payload.android?.notification?.body);
443+
// badge should be set as notification_count in android.notification
444+
assert(payload.android);
445+
assert(payload.android.notification);
446+
assert.equal(payload.android.notification.notification_count, 10);
440447
});
441448

442449
it("should not set 'subtitle' because it is not supported", () => {
@@ -560,10 +567,8 @@ describe('#notifications helper', () => {
560567
assert(payload.data);
561568
assert.equal(payload.data.title, expectedTitle);
562569
assert.equal(payload.data.body, expectedBody);
563-
assert(!payload.data.sound, 'sound should not be in data, it belongs in android.notification');
564-
assert(payload.android);
565-
assert(payload.android.notification);
566-
assert.equal(payload.android.notification.sound, expectedSound);
570+
assert.equal(payload.data.sound, expectedSound, 'sound should be merged into data for silent notifications');
571+
assert(!payload.android, 'android should not be present when only notification fields were set');
567572
});
568573

569574
it('should return valid payload object with v1 structure', () => {

0 commit comments

Comments
 (0)