gruppler
gruppler

Reputation: 686

Service Worker "notificationclick" not firing

The notification is showing fine, but when I click on it, or any of the actions, nothing happens. I see no logging, no error messages, but the notification does close (although it closes even when I comment out the event.notification.close()).

I've tried using the Chrome debugger, and I can set a break point in the code that shows the notification, but all breakpoints within the notificationclick handler fail to pause execution.

I've spent days trying to get this to work and I'm at my wits' end.

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);
  });

Upvotes: 5

Views: 8859

Answers (2)

Luar Faria
Luar Faria

Reputation: 49

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);
});

This code inside service worker js worked fine for me on chrome Desktop and Android.

Upvotes: 1

IgnitedMind
IgnitedMind

Reputation: 367

Hi Could you try below code and see if this is getting called-

 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")
                }
            }))
        }
    });

Edited- Attaching both js files. it is working at my end.

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 file :

/// <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);
            });
    });
}

enter image description here enter image description here

Upvotes: 1

Related Questions