简体   繁体   中英

Firebase Cloud Messaging: Notification Icon Background is only working on second attempt

I am trying to customize the background of a notification icon but I ended up receiving 2 duplicate notifications instead. The first notification doesn't have an icon I've set. The second notification is what I expected.

Here is the picture of my current result.

I've already added firebase-messaging-sw.js to the project and I've added icon in function onBackgroundMessage.

firebase.messaging().onBackgroundMessage(function(payload) {
  // console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
    icon: 'noti_icon.png'
  };

  return self.registration.showNotification(notificationTitle, notificationOptions);
});

I traced back where the first notification came from and I found that it was from firebase-messaging.js and a function onPush which you can see below.

 nt.prototype.onPush = function(a) { return d(this, void 0, void 0, function() { var i, o, s; return h(this, function(e) { let sss = e switch (e.label) { case 0: return (s = function(e) { var t = e.data; if (!t) return null; try { return t.json() } catch (e) { return null } }(a)) ? [4, rt()] : (console.debug("FirebaseMessaging: failed to get parsed MessagePayload from the PushEvent. Skip handling the push."), [2]); case 1: return (i = e.sent(), i.some(function(e) { return "visible" === e.visibilityState && !e.url.startsWith("chrome-extension://") })) ? [2, function(e, t) { var n, r; t.isFirebaseMessaging = !0, t.messageType = _e.PUSH_RECEIVED; try { for (var i = c(e), o = i.next(); !o.done; o = i.next()) { o.value.postMessage(t) } } catch (e) { n = { error: e } } finally { try { o && !o.done && (r = i.return) && r.call(i) } finally { if (n) throw n.error } } }(i, s)] : (o = !1, s.notification ? [4, function(e) { var t = e.actions, n = Notification.maxActions; t && n && t.length > n && console.warn("This browser only supports " + n + " actions. The remaining actions will not be displayed."); return self.registration.showNotification(null !== (n = e.title) && void 0 !== n ? n : "", e) }(((r = p({}, (t = s).notification)).data = ((n = {})[Me] = t, n), r))] : [3, 3]); case 2: e.sent(), o = !0, e.label = 3; case 3: return !0 === o && !1 === this.isOnBackgroundMessageUsed ? [2] : (this.bgMessageHandler && (s = Qe(s), "function" == typeof this.bgMessageHandler ? this.bgMessageHandler(s) : this.bgMessageHandler.next(s)), [4, et(1e3)]); case 4: return e.sent(), [2] } var t, n, r }) })

On the function above, the first notification would go into case 1 with default notification and the second notification would go into case 4.

I don't know how to set notification to show the second notification only.

If it's not a data-only notification, the notification is shown by default. Your call of showNotification shows it once more. The easiest way is to remove your onBackgroundMessage handler and send the icon file name inside the notification (in webpush.notification.icon attribute). Add more info if you need to help with this.

I am trying to customize background notification icon but I ended up receiving 2 duplicate notifications instead.
1st notification doesn't have an icon I've set.
2nd notification is what I expected.

Here is the picture of my current result.

I've already added firebase-messaging-sw.js to the project and I've added icon in function onBackgroundMessage.

firebase.messaging().onBackgroundMessage(function(payload) {
  // console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
    icon: 'noti_icon.png'
  };

  return self.registration.showNotification(notificationTitle, notificationOptions);
});

I traced back where the first notification came from and I found that it was from firebase-messaging.js

nt.prototype.onPush = function(a) {
                return d(this, void 0, void 0, function() {
                    var i, o, s;
                    return h(this, function(e) {
                        let sss = e
                        switch (e.label) {
                            case 0:
                                return (s = function(e) {
                                    var t = e.data;
                                    if (!t) return null;
                                    try {
                                        return t.json()
                                    } catch (e) {
                                        return null
                                    }
                                }(a)) ? [4, rt()] : (console.debug("FirebaseMessaging: failed to get parsed MessagePayload from the PushEvent. Skip handling the push."), [2]);
                            case 1:
                                return (i = e.sent(), i.some(function(e) {
                                    return "visible" === e.visibilityState && !e.url.startsWith("chrome-extension://")
                                })) ? [2, function(e, t) {
                                    var n, r;
                                    t.isFirebaseMessaging = !0, t.messageType = _e.PUSH_RECEIVED;
                                    try {
                                        for (var i = c(e), o = i.next(); !o.done; o = i.next()) {
                                            o.value.postMessage(t)
                                        }
                                    } catch (e) {
                                        n = {
                                            error: e
                                        }
                                    } finally {
                                        try {
                                            o && !o.done && (r = i.return) && r.call(i)
                                        } finally {
                                            if (n) throw n.error
                                        }
                                    }
                                }(i, s)] : (o = !1, s.notification ? [4, function(e) {
                                    var t = e.actions,
                                        n = Notification.maxActions;
                                    t && n && t.length > n && console.warn("This browser only supports " + n + " actions. The remaining actions will not be displayed.");
                                    return self.registration.showNotification(null !== (n = e.title) && void 0 !== n ? n : "", e)
                                }(((r = p({}, (t = s).notification)).data = ((n = {})[Me] = t, n), r))] : [3, 3]);
                            case 2:
                                e.sent(), o = !0, e.label = 3;
                            case 3:
                                return !0 === o && !1 === this.isOnBackgroundMessageUsed ? [2] : (this.bgMessageHandler && (s = Qe(s), "function" == typeof this.bgMessageHandler ? this.bgMessageHandler(s) : this.bgMessageHandler.next(s)), [4, et(1e3)]);
                            case 4:
                                return e.sent(), [2]
                        }
                        var t, n, r
                    })
                })

On this function, the first notification would go into case 1 with default notification and the second notification would go into case 4

I don't know how to set notification to show the second notification only.

const notificationOptions = {
    body: payload.notification.body,
    icon: 'noti_icon.png',
    type: json
  };

Have you tried this?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM