【问题标题】:Service Worker "notificationclick" not firing服务工作者“notificationclick”未触发
【发布时间】:2020-11-11 21:06:41
【问题描述】:

通知显示正常,但是当我单击它或执行任何操作时,什么都没有发生。我没有看到任何日志记录,也没有错误消息,但通知确实关闭了(尽管即使我注释掉 event.notification.close() 它也会关闭)。

我尝试使用 Chrome 调试器,并且可以在显示通知的代码中设置断点,但 notificationclick 处理程序中的所有断点都无法暂停执行。

我花了几天的时间试图让它工作,但我束手无策。

const auth = firebase.auth();
const functions = firebase.functions();
const done = functions.httpsCallable("done");
const snooze = functions.httpsCallable("snooze");

self.addEventListener("notificationclick", event => {
  console.log("notificationclick", event);
  const uid = auth.currentUser.uid;
  const { id, url } = event.notification.data;

  event.notification.close();
  event.waitUntil(() => {
    switch (event.action) {
      case "done":
        console.log("Done");
        return done({ uid, id });
      case "snooze1":
        console.log("Snooze 1 Hour");
        return snooze({ uid, id, hours: 1 });
      case "snooze24":
        console.log("Snooze 1 Day");
        return snooze({ uid, id, hours: 24 });
      default:
        console.log("Open App");
        return clients
          .matchAll({
            includeUncontrolled: true,
            type: "window"
          })
          .then(clientList => {
            for (let i = 0; i < clientList.length; i++) {
              let client = clientList[i];
              if (url[0] === "#") {
                if (client.url.endsWith(url) && "focus" in client) {
                  return client.focus();
                }
              } else {
                if (
                  client.url.replace(/#.*$/, "") === url &&
                  "focus" in client
                ) {
                  return client.focus();
                }
              }
            }
            if (clients.openWindow) {
              return clients.openWindow(location.origin + url);
            }
          });
    }
  });
});

firebase
  .messaging()
  .setBackgroundMessageHandler(({ data: { title, options } }) => {
    options = JSON.parse(options);
    options.actions = [
      { action: "done", title: "Done" },
      { action: "snooze1", title: "Snooze 1 Hour" },
      { action: "snooze24", title: "Snooze 1 Day" }
    ];

    return self.registration.showNotification(title, options);
  });

【问题讨论】:

    标签: web-notifications


    【解决方案1】:

    你好,你可以试试下面的代码,看看它是否被调用-

     self.addEventListener('notificationclick', function (event) {
            event.notification.close();
            var redirectUrl = null;
            var tag = event.notification.tag;
            if (event.action) {
                redirectUrl = event.action
            } 
            if (redirectUrl) {
                event.waitUntil(async function () {
                    var allClients = await clients.matchAll({
                        includeUncontrolled: !0
                    });
                    var chatClient;
                    for (const client of allClients) {
                        if (redirectUrl != '/' && client.url.indexOf(redirectUrl) >= 0) {
                            client.focus();
                            chatClient = client;
                            break
                        }
                    }
                    if (chatClient == null || chatClient == 'undefined') {
                        chatClient = clients.openWindow(redirectUrl);
                        return chatClient
                    }
                }().then(result => {
                    if (tag) {
                        //PostAction(tag, "click")
                    }
                }))
            }
        });
    

    编辑- 附加两个js文件。它在我的最后工作。

    firebase-messaging-sw.js
    

    importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
    importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');
    var config = {
        apiKey: "your api key",
        authDomain: "you firebase domain",
        databaseURL: "your firbase db url",
        projectId: "your project id",
        storageBucket: "",
        messagingSenderId: "sender id"
    };
    
    firebase.initializeApp(config);
    const messaging = firebase.messaging();
    messaging.setBackgroundMessageHandler(function (payload) {
        console.log('[firebase-messaging-sw.js] Received background message ', payload.data);    
        var notificationTitle = payload.data.Title;
        var notificationOptions = {
            body: payload.data.Body,
            icon: payload.data.Icon,
            image: payload.data.Image,
            action: payload.data.ClickAction
        };
        console.log("strated sending msg" + notificationOptions);
        return self.registration.showNotification(notificationTitle,notificationOptions);
    });
    
    self.addEventListener('notificationclick', function (event) {
        console.log('On notification click: ', event.notification);
        event.notification.close();
        var redirectUrl = null;
        if (event.notification.data) {
            if (event.notification.data.FCM_MSG) {
                redirectUrl = event.notification.data.FCM_MSG.data ? event.notification.data.FCM_MSG.data.click_action : null
            } else {  
                redirectUrl = event.notification.data ? event.notification.data.click_action : null
            }
        }
        console.log("redirect url is : " + redirectUrl);
    
        if (redirectUrl) {       
            event.waitUntil(async function () {
                var allClients = await clients.matchAll({
                    includeUncontrolled: true
                });
                var chatClient;            
                for (var i = 0; i < allClients.length; i++) {
                    var client = allClients[i];                
                    if (client['url'].indexOf(redirectUrl) >= 0) {
                        client.focus();
                        chatClient = client;
                        break;
                    }
                }
                if (chatClient == null || chatClient == 'undefined') {
                    chatClient = clients.openWindow(redirectUrl);
                    return chatClient;
                }
            }());        
        }
    });
    
    self.addEventListener("notificationclose", function (event) {
        event.notification.close();
        console.log('user has clicked notification close');    
    });

    application.js 文件:

    /// <reference path="scripts/jquery-3.3.1.js" />
    
    try {
    var config = {
        apiKey: "your api key",
        authDomain: "you firebase domain",
        databaseURL: "your firbase db url",
        projectId: "your project id",
        storageBucket: "",
        messagingSenderId: "sender id"
    };
    firebase.initializeApp(config);
    
        if ('serviceWorker' in navigator && 'PushManager' in window) {
        console.log('Service Worker and Push is supported');
    
        navigator.serviceWorker
            .register('/firebase-messaging-sw.js')
            .then((swReg) => {
                firebase.messaging().useServiceWorker(swReg);
                askForPermissioToReceiveNotifications();            
            })
            .catch(function (error) {
                console.error('Service Worker Error', error);
                window.alert("Service Worker Error" + error);
            })
    } else {
            console.warn('Push messaging is not supported');        
            window.alert("Push messaging is not supported " + (navigator.serviceWorker));    
    }
    
    const askForPermissioToReceiveNotifications = async () => {
        try {                    
                        const messaging = firebase.messaging();
                        console.log(messaging);
                        await messaging.requestPermission();
                        const token = await messaging.getToken();                    
                        if (token !== null || token !== 'undefined') {
                            await sendDeviceTokenToServerSide(token);
                        }                    
                        console.log('Got token : ' + token);
                        messaging.onMessage(function (payload) {
                            console.log('onMessage: ', payload);
                            setTimeout(() => {
                                navigator.serviceWorker.ready.then(function (registration) { 
                                    var notificationTitle = payload.notification.title;
                                    var notificationOptions = {
                                        body: payload.notification.body,
                                        data: payload.data,
                                        icon: payload.notification.icon,
                                        image: payload.data.Image,
                                        requireInteraction: payload.notification.requireInteraction,
                                        tag: payload.notification.tag,
                                        click_action: payload.data.click_action,
                                        requireInteraction: true
                                    };
                                    registration.showNotification(notificationTitle, notificationOptions);
                                },50)
                            });                                                
                        }); 
        }
        catch (e) { console.log('error in getting token: ' + e); window.alert("error in getting token: " + e); } 
     }
    
    function sendDeviceTokenToServerSide(token) {
            $.ajax({
                type: 'POST',
                url: '/Home/StoreToken',
                timeout: 5000000,           
                data: { token: token },
                success: function (success) {                
                    console.log("device token is sent to server");                                
                },
                error: function (error) {
                    console.log("device error sending token to server : " + error);
                    window.alert("device error sending token to server : " + error);
                }
            });
    }
    } catch (e) {
        window.alert("error: " + e);
    }
    
    function GetFcmUserToken(messaging) {
        messaging.onTokenRefresh(function () {
            messaging.getToken()
                .then(function (refreshedToken) {
                    console.log('Token refreshed.');               
                    return refreshedToken;
                })
                .catch(function (err) {
                    console.log('Unable to retrieve refreshed token ', err);
                    showToken('Unable to retrieve refreshed token ', err);
                });
        });
    }

    【讨论】:

    • 你的代码和我的代码一样。
    • 你的代码在 serviceworker.js/firebase-messaging-sw.js 下对吗?
    • 是的,文件中的其余代码正在运行。我就是无法触发点击处理程序。
    • 当网站同时处于前台和后台或仅在后台时会发生这种情况?
    • 该通知仅在网站处于后台时出现。我认为这种行为是由 Firebase 消息处理的。
    【解决方案2】:
    self.addEventListener('notificationclick', function (event) {
    const clickedNotification = event.notification;
    // Do something as the result of the notification click
    const promiseChain = clients.openWindow(clickedNotification.data.Url);
    event.waitUntil(promiseChain);
    });
    

    Service Worker js 中的这段代码在 Chrome 桌面和 Android 上运行良好。

    【讨论】:

      猜你喜欢
      • 2019-01-04
      • 2022-06-24
      • 1970-01-01
      • 2021-02-07
      • 2021-06-17
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多