Issue metadata
Sign in to add a comment
|
Push event appears to not be firing in ServiceWorker
Reported by
bhhro...@justin.tv,
Jun 23 2017
|
||||||||||||||||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36 Steps to reproduce the problem: 1. Register a service worker, and create a push subscription. 2. Send a message using the provided push subscription information(signed using draft 1 of the vapid spec). 3. Witness that response code for sending of message is 201 and message is properly received by browser without decryption errors(used gcm-internals within chrome inspector). However, event handler for push event of registered ServiceWorker never fires. What is the expected behavior? push event handler fires when receiving a message corresponding to its pushsubscription. What went wrong? push event handler doesn't appear to fire. All appears to be fine when following steps from: https://developers.google.com/web/fundamentals/engage-and-retain/push-notifications/common-issues-and-reporting-bugs#payload_encryption_issue The only thing that seems slight off is that the next check-in event is five days in the past. Attaching a bunch of screenshots from chrome inspector for gcm-internals and service-workers. Did this work before? Yes Unsure Does this work in other browsers? Yes Chrome version: 59.0.3071.86 Channel: n/a OS Version: OS X 10.11.6 Flash Version: Shockwave Flash 26.0 r0 Providing subscription info for you: "auth": "2dqQp1-oBRcpLruGbczfYw==", "endpoint": "https://fcm.googleapis.com/fcm/send/fQpFz3738fo:APA91bGsn85wRqkvaPXV_OvnBtAYki9Jdbs1cy8qotNe_aSC0Wu9FTUXc7oYgG8oXv6Y2ypCB8OQnhYk_K1yaCIJ5hqo5fGAyixYUxpEA0T-_4y0hhQN8XYUnk3T-IeB4Ax4n4i_j9iS", "p256dh": "BD_ImCvxxVRvVhyuvV3XlZATPGjhp1-xX0dgTx5Yg35q2GEguA6CLrW-kH8eeckbj-VSEiXKeqZxmoXg_OXRaYU="
,
Jun 26 2017
,
Jul 6 2017
Sorry for the delay!
I have reproduced and copied in the histograms below. For additional context, I noticed that the first push event after browser restart appears to be firing as expected, while none of the subsequent events are rendering notifications. The below histograms are for the initial successful render plus an unrendered second notification.
GCM:
Histogram: GCM.ConnectedViaProxy recorded 1 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 100.0%)
1 ...
Histogram: GCM.ConnectionEndpoint recorded 1 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 100.0%)
1 ...
Histogram: GCM.ConnectionLatency recorded 1 samples, mean = 331.0 (flags = 0x41)
0 ...
317 ------------------------------------------------------------------------O (1 = 100.0%) {0.0%}
389 ...
Histogram: GCM.ConnectionSuccessRate recorded 1 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (1 = 100.0%) {0.0%}
2 O (0 = 0.0%) {100.0%}
Histogram: GCM.Crypto.DecryptMessageResult recorded 2 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (2 = 100.0%) {0.0%}
2 ...
Histogram: GCM.Crypto.GetKeySuccessRate recorded 2 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (2 = 100.0%) {0.0%}
2 O (0 = 0.0%) {100.0%}
Histogram: GCM.Crypto.InitKeyStoreSuccessRate recorded 1 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (1 = 100.0%) {0.0%}
2 O (0 = 0.0%) {100.0%}
Histogram: GCM.Crypto.LoadKeyStoreSuccessRate recorded 1 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (1 = 100.0%) {0.0%}
2 O (0 = 0.0%) {100.0%}
Histogram: GCM.DataMessageBurstReceivedInterval recorded 1 samples, mean = 50714.0 (flags = 0x41)
0 ...
37840 ------------------------------------------------------------------------O (1 = 100.0%) {0.0%}
51267 ...
Histogram: GCM.DataMessageReceived recorded 2 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (2 = 100.0%) {0.0%}
2 O (0 = 0.0%) {100.0%}
Histogram: GCM.DataMessageReceivedHasCollapseKey recorded 2 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (2 = 100.0%)
1 ...
Histogram: GCM.DataMessageReceivedHasRegisteredApp recorded 2 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (2 = 100.0%) {0.0%}
2 O (0 = 0.0%) {100.0%}
Histogram: GCM.Database.Open recorded 1 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 100.0%)
1 ...
Histogram: GCM.FirstReceivedDataMessageLatencyAfterConnection recorded 1 samples, mean = 65530.0 (flags = 0x41)
0 ...
10000 ------------------------------------------------------------------------O (1 = 100.0%) {0.0%}
Histogram: GCM.LoadStatus recorded 1 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 100.0%)
1 ...
Histogram: GCM.NumThrottledApps recorded 1 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 100.0%)
1 ...
Histogram: GCM.ReceivedDataMessageBurstSize recorded 1 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (1 = 100.0%) {0.0%}
2 ...
Histogram: GCM.RestoredIncomingMessages recorded 1 samples, mean = 3.0 (flags = 0x41)
0 ...
3 ------------------------------------------------------------------------O (1 = 100.0%) {0.0%}
4 ...
Histogram: GCM.RestoredOutgoingMessages recorded 1 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 100.0%)
1 ...
Histogram: GCM.RestoredRegistrations recorded 1 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (1 = 100.0%) {0.0%}
2 ...
Histogram: GCM.StoreSizeKB recorded 1 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 100.0%)
1 ...
Histogram: GCM.StoreUpdateSucceeded recorded 5 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (5 = 100.0%) {0.0%}
2 O (0 = 0.0%) {100.0%}
Histogram: GCM.UserSignedIn recorded 1 samples, mean = 1.0 (flags = 0x41)
0 O (0 = 0.0%)
1 ------------------------------------------------------------------------O (1 = 100.0%) {0.0%}
2 O (0 = 0.0%) {100.0%}
Notifications:
Histogram: Notifications.AuthorDataSize recorded 2 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (2 = 100.0%)
1 ...
Histogram: Notifications.Database.DeleteBeforeWriteResult recorded 2 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (2 = 100.0%)
1 ...
Histogram: Notifications.Database.DestroyResult recorded 1 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 100.0%)
1 ...
Histogram: Notifications.Database.OpenResult recorded 1 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 100.0%)
1 ...
Histogram: Notifications.Database.ReadForServiceWorkerResult recorded 2 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (2 = 100.0%)
1 ...
Histogram: Notifications.Database.WriteResult recorded 2 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (2 = 100.0%)
1 ...
Histogram: Notifications.LoadFileSize.Icon recorded 2 samples, mean = 3456.0 (flags = 0x41)
0 ...
2786 ------------------------------------------------------------------------O (2 = 100.0%) {0.0%}
3865 ...
Histogram: Notifications.LoadFinishTime.Icon recorded 2 samples, mean = 2.5 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 50.0%)
1 ...
5 ------------------------------------O (1 = 50.0%) {50.0%}
7 ...
Histogram: Notifications.PersistentNotificationActionCount recorded 2 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (2 = 100.0%)
1 ...
PushMessaging:
Histogram: PushMessaging.DeliveryStatus recorded 2 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (2 = 100.0%)
1 ...
Histogram: PushMessaging.DeliveryStatus.FindServiceWorker recorded 2 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (2 = 100.0%)
1 ...
Histogram: PushMessaging.DeliveryStatus.ServiceWorkerEvent recorded 2 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (2 = 100.0%)
1 ...
Histogram: PushMessaging.ReceivedMessageInBackground recorded 2 samples, mean = 0.0 (flags = 0x41)
0 ------------------------------------------------------------------------O (2 = 100.0%)
1 ...
Histogram: PushMessaging.UserVisibleStatus recorded 2 samples, mean = 1.5 (flags = 0x41)
0 ------------------------------------------------------------------------O (1 = 50.0%)
1 ...
3 ------------------------------------------------------------------------O (1 = 50.0%) {50.0%}
4 ...
,
Jul 6 2017
PushMessaging.UserVisibleStatus provides the value here: both push events were received by the Service Worker and had to show a notification (i.e. there were no open windows), but only one did. The other message consumed engagement budget to skip showing it. However, Notifications.Database.WriteResult indicates that two notifications were shown. Similarly, Notifications.LoadFinishTime.Icon tells me that two icons were loaded too, both having the same size (~2786 bytes). This indicates to me that there's likely an issue with your Service Worker JavaScript code. Would you be able to share code for the `push` event?
,
Jul 6 2017
Thanks Peter, no problem!
self.addEventListener('push', function(event) {
if (event.data) {
event.waitUntil(
idbKeyval.get('userId')
.then(function(userId) {
fireNotification(event, userId);
})
);
} else {
console.warn('Empty push data');
}
});
function fireNotification(event, userId) {
let j = event.data.json();
let body = j['body'];
let icon = j['icon'];
let redirectURL = j['redirect_url'];
let messageUserId = j['user_id'];
//Only show messages for the most recently logged in user
if (String(messageUserId) === String(userId)) {
self.registration.showNotification(body, {
icon: icon,
tag: redirectURL
});
}
}
,
Jul 6 2017
Ah, there we go!
In your Service Worker's `push` event it's important that you wait until the notification has been shown. In practice you'd write the code like:
self.addEventListener('push', event => {
event.waitUntil(registration.showNotification(...));
});
In your code, you can easily update it by returning a promise from fireNotification (either the one from the showNotification() call or just a Promise.resolve() in the error case) and returning that from the call in the `push` event as well:
self.addEventListener('push', function(event) {
if (event.data) {
event.waitUntil(
idbKeyval.get('userId')
.then(function(userId) {
return fireNotification(event, userId);
})
);
} else {
console.warn('Empty push data');
}
});
function fireNotification(event, userId) {
let j = event.data.json();
let body = j['body'];
let icon = j['icon'];
let redirectURL = j['redirect_url'];
let messageUserId = j['user_id'];
//Only show messages for the most recently logged in user
if (String(messageUserId) === String(userId)) {
return self.registration.showNotification(body, {
icon: icon,
tag: redirectURL
});
}
return Promise.resolve();
}
On a tangent, when the user is not the one logged in anymore you may want to unregister the push subscription. I don't know how relevant that is in your model.
,
Jul 6 2017
Thanks, Peter! However, that didn't actually appear to be the issue. I do believe I did find what the issue was though, it appears to be silencing subsequent push messages due to having the same tag. I believe there appears to be a bit of a mismatch between tag behavior and the behavior stated in the doc, though, as my understanding was that multiple pushes having the same tag should still render. According to https://developers.google.com/web/updates/2015/03/push-notifications-on-the-open-web: "The notification tag acts as an identifier for unique notifications. If we sent two push messages to the same endpoint, with a short delay between them, and display notifications with the same tag, the browser will display the first notification and replace it with the second notification when the push message is received."
,
Jul 6 2017
Oh, and in response to your tangent. Yeah, I had actually considered explicitly unregistering the push subscription on logout events, but it seemed like doing the filtering at message receive time led to a bit cleaner scenario around handling of implicit logout events(such as session cookie expiration).
,
Jul 7 2017
> multiple pushes having the same tag should still render
If you post two notifications having the same tag, only one will be presented to the user (the latest one). The following code will show *one* notification having "Second!" as its title:
swRegistration.showNotification('First!', { tag: 'foo' })
.then(() => swRegistration.showNotification('Second!', { tag: 'foo' }));
Is that what's happening here?
There is a race condition to be aware of: we fire `push` events when they come in. That means that when a user regains connectivity and there's several push messages queued up, we'll fire them pretty much at the same time, so if fetches or other asynchronous operations take longer for the first notification than the second they may end up replacing each other in the wrong order.
,
Jul 10 2017
Hi Peter, For my repro case, both notifications have the same body. I didn't see anything in the docs that would suggest that that should be a problem. Am I wrong in that understanding? Thanks, Brent
,
Jul 13 2017
No, that should be fine. I don't understand what the problem is then - any number of notifications posted with the same tag, regardless of content, will coalesce to a single one. If you'd like to have multiple, they need to have different tags...
,
Jul 13
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue. Sorry for the inconvenience if the bug really should have been left as Available. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Jul 31
This seems fixed to me. Please re-open if that's not the case |
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by joh...@chromium.org
, Jun 26 2017