Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS 9.0.2 - Notification Twice using onBackgroundMessage #5516

Closed
SylvainAssemat opened this issue Sep 19, 2021 · 15 comments · Fixed by #5762
Closed

JS 9.0.2 - Notification Twice using onBackgroundMessage #5516

SylvainAssemat opened this issue Sep 19, 2021 · 15 comments · Fixed by #5762

Comments

@SylvainAssemat
Copy link

SylvainAssemat commented Sep 19, 2021

Hi

I'm in trouble testing the push event using the JS 9.0.2 (module) => via onBackgroundMessage in a service worker
I m aware that i dont have to send a notification in the payload so i just send data (via postman) :

{
   "to": "/topics/public",
    "data": {
        "body": "Notification in Body",
        "title": "Notification in Title",
        "url": "http://www.google.fr"
    }
}

When i customize my notification using self.registration.showNotification, i have 2 notification displaying.

This one : (This site has been updated in the background) should not appear
And my custom notification.

I have checked that the payload dont have any "notification" stuff.

I should miss something or maybe a bug ?

Thanks for any help

@google-oss-bot
Copy link
Contributor

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@jbalidiong
Copy link
Contributor

Hi @SylvainAssemat , thanks for the report. I was able to reproduce the behavior. Let me check what we can do for this issue or bring someone here that can provide more context about it. I’ll update this thread if I have any information to share.

@Feiyang1
Copy link
Member

Feiyang1 commented Sep 22, 2021

Sounds like the same issue as #3725. I thought it was fixed though - @zwu52

@zwu52
Copy link
Member

zwu52 commented Oct 6, 2021

@SylvainAssemat ,
could you paste your onBackrgoundMessage callback. So there is a timer ran for each onPush callback and the showNotification call needs to happen before the timer depletes. Asking because I suspecting yours is running slower for some reason.

@SylvainAssemat
Copy link
Author

SylvainAssemat commented Oct 9, 2021

Hi all

@zwu52 , here is the service worker file including the onBackgroundMessage.

I have found a strange behaviour.
Today i test this double notification since my first issue , but i could not reproduce the bug.
I was so surprised !

But ...

When everything work well (tested many times), i begin to add just :

self.addEventListener('push', event => {
    console.log('[firebase-messaging-sw.js] Received PUSH event ', event);
});

What a bad idea ... , i could not make it work again since this modification.
Double notification is back :-(
(Even when i delete this listener)

Maybe there is something to investigate

import {
    initializeApp
} from "https://www.gstatic.com/firebasejs/9.1.2/firebase-app.js";

import {
    getMessaging,
    onBackgroundMessage
} from "https://www.gstatic.com/firebasejs/9.1.2/firebase-messaging-sw.js";


const firebaseApp = initializeApp({ 
	// MYCONFIG voluntarily hidden for github 
});

const messaging = getMessaging(firebaseApp);

onBackgroundMessage(messaging, (payload) => {
	console.log('[firebase-messaging-sw.js] Received background message ', payload);

	if (!(self.Notification && self.Notification.permission === 'granted')) {
        return;
    }
   
    self.registration.showNotification(payload.data.title, {
        body: payload.data.body,
        icon:  '/pwa/icon-512x512.png',
        badge: '/favicon.ico',
        tag: 'renotify',
		renotify: true,
		//actions: [{action: 'google', url: "https://www.google.fr"}]
    })
    .then(() => self.registration.getNotifications())
    .then(notifications => {
        setTimeout(() => notifications.forEach(notification => notification.close()), 3000);
    });

});
@zwu52
Copy link
Member

zwu52 commented Oct 11, 2021

The FCM SDK registers a onPush listener internally. Per Multiple identical event listeners, your listener could lead the FCM one being discarded. If that's the case, FCM SDK wouldn't function properly. But if you want to have your own onPush listener without the silent push warning, you also need to call showNotification inside. I doubt that's your goal so have you tried to clear the sites' cache when you removed your onPush listener?

Another tip is on using the onBackgroundMessage method is to always call showNotification 1st line to make sure the silent push check doesn't get triggered.

@SylvainAssemat
Copy link
Author

SylvainAssemat commented Oct 11, 2021

HI

i made a simple example with only 3 files below, to show the generic chrome notification is displayed even if i call showNotification ASAP in the onBackgroundMessage.

  • index.html
  • firebase-messaging.js
  • firebase-messaging-sw.js

If you have time to try it and reproduce (or not) the behavior, just fill the missing configuration inside :

  • a firebase config json (in both js file)
  • a vapidKey

Index.html

<!doctype html>
<html lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="msapplication-tap-highlight" content="no" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" />
	<!--[if lt IE 9]>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
	<![endif]-->
<style></style>
</head>
<body>
	<div class="container" style="height: calc(100% - 64px);">
		<h1>HELLO</h1>
	</div>
	  
	<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
	<script type="module" src="/firebase-messaging.js"></script>
	<script>
		window.addEventListener('load', () => {
			console.log("window.onload READY");
			M.AutoInit();
		});	
	</script>
	
</body>
</html>

firebase-messaging.js

import {
    initializeApp
} from "https://www.gstatic.com/firebasejs/9.1.2/firebase-app.js";

import {
    getMessaging,
	getToken,
	onMessage
} from "https://www.gstatic.com/firebasejs/9.1.2/firebase-messaging.js";

const firebaseApp = initializeApp({ 
	
});

const messaging = getMessaging(firebaseApp);

onMessage(messaging, (payload) => {
	console.log('[firebase-messaging.js] Received foreground message ', payload);
	
	if (!(self.Notification && self.Notification.permission === 'granted')) {
        return;
    }
    
    Notification.requestPermission()
      .then((permission) => {
        if (permission === "granted"){

			var notification = new Notification(payload.data.title, { 
				body: payload.data.body, 
		        icon:  '/pwa/icon-512x512.png',
		        badge: '/favicon.ico',
		        tag: 'renotify',
		  		renotify: true,
		  		//"actions": [
				//	{ "action": "yes", "title": "Yes", "icon": "images/yes.png" },
				//    { "action": "no", "title": "No", "icon": "images/no.png" }
				//]
			});
			notification.onclick = function() { 
				console.log(console.log(this)); 
			};
		
			setTimeout(() => {
				notification.close();
			}, 3000);
		}
	})
	
});


if ('serviceWorker' in navigator) {

	/*
	navigator.serviceWorker.getRegistrations().then(function(registrations) {
	 	for(let registration of registrations) {
	  		registration.unregister()
		}
	});
	*/
	
	navigator.serviceWorker.register('/firebase-messaging-sw.js', { type: 'module'}) 
		.then(registration => {
			console.log('😎 Le Service Worker (firebase-messaging-sw.js) démarre');

              	getToken(messaging, { 
					vapidKey: "-- FILL IT --" ,
					serviceWorkerRegistration: registration
				})
	            .then(function (token) {
	                console.log(token);
				})
	            .catch(function (err) {
	                console.error("Didn't get notification permission", err);
	            });		              	

        })
     	.catch(error => {
       		console.error('😥 L\'enregistrement (firebase-messaging-sw.js) ne s\'est pas bien passé :', error);
     	});
	
}

firebase-messaging-sw.js

import {
    initializeApp
} from "https://www.gstatic.com/firebasejs/9.1.2/firebase-app.js";

import {
    getMessaging,
    onBackgroundMessage
} from "https://www.gstatic.com/firebasejs/9.1.2/firebase-messaging-sw.js";


const firebaseApp = initializeApp({ 
	
});

const messaging = getMessaging(firebaseApp);

onBackgroundMessage(messaging, (payload) => {
	
	self.registration.showNotification(payload.data.title, {
        body: payload.data.body,
        icon:  '/pwa/icon-512x512.png',
        badge: '/favicon.ico',
        //tag: 'renotify',
		//renotify: true,
		//actions: [{action: 'google', url: "https://www.google.fr"}]
    })
    .then(() => self.registration.getNotifications())
    .then(notifications => {
        setTimeout(() => notifications.forEach(notification => notification.close()), 3000);
    });

	console.log('[firebase-messaging-sw.js] Received background message ', payload);

	/*if (!(self.Notification && self.Notification.permission === 'granted')) {
        return;
    }*/

});

self.addEventListener('install', (e) => {
    console.log(`** Installation du service worker firebase-messaging-sw.js`);
    self.skipWaiting(); //Force activation si MAJ
});

self.addEventListener('activate', (e) => {
    console.log(`** Activation du service worker firebase-messaging-sw.js`);
});

@zwu52
Copy link
Member

zwu52 commented Oct 22, 2021

@SylvainAssemat Thanks for sharing. I am not reproducing the issue.

What happens if you time this block

self.registration.showNotification(payload.data.title, {
        body: payload.data.body,
        icon:  '/pwa/icon-512x512.png',
        badge: '/favicon.ico',
        //tag: 'renotify',
		//renotify: true,
		//actions: [{action: 'google', url: "https://www.google.fr"}]
    })

I wonder if for some reason this is slow running on your machine

@google-oss-bot
Copy link
Contributor

Hey @SylvainAssemat. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

@google-oss-bot
Copy link
Contributor

Since there haven't been any recent updates here, I am going to close this issue.

@SylvainAssemat if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.

@Eros1990
Copy link

I created a simple web extension able to receive messages and i experienced the same issue reported by @SylvainAssemat.
Any update about this bug?

This is my service worker:

import { initializeApp } from 'firebase/app';
import { getMessaging } from 'firebase/messaging/sw';
import { onBackgroundMessage } from 'firebase/messaging/sw';

const firebaseConfig = {
    <firebase-configuration>
};

initializeApp(firebaseConfig);

var messaging = getMessaging();

onBackgroundMessage(messaging, (payload) => {
    console.log('[firebase-messaging-sw.js] Received background message ', payload);
    if(payload.notification === undefined){
        const notificationTitle = 'Test data message';
        self.registration.showNotification(notificationTitle);
    }
});
@zwu52
Copy link
Member

zwu52 commented Nov 11, 2021

Eros,
See above. Try call showNotification 1st thing and see if it resolves. Also, I think you may skip the if check sense the SDK should handle that logic (if there is a notification payload, the payload will be routed to onMessage otherwise onBackgroundMessage)

@Eros1990
Copy link

Hi @zwu52 , calling showNotification as first thing the problem persists.

onBackgroundMessage code:

onBackgroundMessage(messaging, (payload) => {
    self.registration.showNotification("Test");
});

Result:
notifications

@zwu52
Copy link
Member

zwu52 commented Nov 11, 2021

hmm. The only solution I can think of now is to add 1-2 seconds to the timer. I'll try make that change in the next release.

@Eros1990
Copy link

Eros1990 commented Nov 12, 2021

Thanks @zwu52,
in my humble opinion, I think that changing this line adding an await and rewriting the onBackgroundMessage like this:

onBackgroundMessage(messaging, (payload) => {
    return self.registration.showNotification("Test");
});

the problem should be resolved.

@firebase firebase locked and limited conversation to collaborators Dec 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.