Hacker News new | past | comments | ask | show | jobs | submit login
Demystifying Web Push Notifications (pqvst.com)
212 points by daco 11 months ago | hide | past | favorite | 83 comments



> ChatGPT struggled to generate any good code for me, and I also struggled to find any minimal clear explanations online.

The two are probably related...


Web push is basically useless because Google hasn't prioritized fixing the issues causing Android to delay the notifications by 10 minutes or more. They are basically only useful for "re-engagement" spam, nothing time critical.

https://bugs.chromium.org/p/chromium/issues/detail?id=777106

There are a whole bunch of sad bugs about Web Push in the issue tracker. It's disappointingly typical of the PWA APIs. They sound like they have the capabilities you need until you try to use them and uncover a minefield of five year old known issues that will never be fixed.


It's worth noting that this is almost certainly a deliberate policy to push Firebase Cloud Messaging signups & inclusion of accompanying blobs in 3rd-party Android apps.

Even within the non-PWA app world, low adoption of initiatives like UnifiedPush[0] & Android OpenPush[1] mean the canonical way for even open-source Android apps to do efficient push is by including proprietary Google blobs for FCM support, all mediated through Google servers. This is by far the biggest blocker for otherwise FOSS apps to distribute "clean" releases without proprietary code.

If Google are putting up these kind of hurdles for app store apps, it makes sense they wouldn't make it any better for PWAs.

[0] https://unifiedpush.org/

[1] https://bubu1.eu/openpush/


I don't believe it's any kind of conspiracy to make life hard for open source apps. There are legitimate technical reasons to use a single service for push messaging. This is just a regular old case of bad incentives. Chrome doesn't do a good job of prioritizing issues with user impact and Android doesn't support other teams well.


I don’t believe that “conspiracy” is the right word, but I don’t believe your post does the situation justice either. I think it is easy to find yourself in a situation - through no intentional planning of your own - where you have a difficult problem to solve and you don’t stand to benefit from doing so (or, even worse, you lose from do that). You are acknowledging the first part but not the second.


> I don't believe it's any kind of conspiracy to make life hard for open source apps.

This is an odd framing of something that generates revenue & provides valuable analytical data - obviously Google aren't doing this just to make life harder for open source apps, that's just a knock-on effect of lock-in in general.

> There are legitimate technical reasons to use a single service for push messaging.

This is only true if you're referring to local daemons as "services" (e.g. Play Services), not remotely hosted services as is the case here (e.g. FCM). There's zero reason Play couldn't support multiple providers as UnifiedPush, etc. do. Just as there's no technical reason not to properly support Web Push.


As far as I can tell the story was something along the line of:

1. design push notifications as technical solution but not the necessary UX/UI and any abuse mitigations making them the perfect tool for abuse (both Chrome and FF, on Windows I only have seen Chrome impl. and it was horrible)

2. oh dang it get's abused

3. add abuse mitigations

4. which do not really mitigate the abuse at all but do prevent any proper use

The the 4th point is the wtf something seems fishy point.

If they would outright removed it arguing "too much abuse" I would not have been surprised.

If they had tried to add proper abuse migrations and failed I would not have been surprised.

But they added migrations which very obviously would not fix the most common wide spread abuse but would kill most proper use. And where that isn't a unexpected result, but a very easily predictable result.

And that is what is strange because it is as if they kept it around as a pretense at the cost of a lot of non technical users "safety/experience" and iff that was intentionally I would guess it's to cause enough damage so that external institutes like consumer safety groups ask for it to be removed. Which if that would be the case would be quite disgusting.

Firefox could fix that by fixing the UI/UX abuse issue (it's all about things outside of the web standard, i.e. doable without changing the standard). But as far as I can tell they do not care, and either implemented it for feature compatibility with chrome or I think the now gone FirefoxOS.


> They sound like they have the capabilities you need

I'm curious about what sounds so endearing about them to app developers. I wrote a WebPush scheduler once that implemented the VAPID protocol. Along the road I came across a myriad of resources that hinted at the fact that it's a heavily restricted feature, due to the fact that browser vendors know it's mostly abused for spam. I kinda figured you wouldn't implement them unless you're forced to explore any avenue for engagement.


Theoretically you might use them for a calendar app reminding people of upcoming appointments, a video call app receiving a call, or things along those lines.

Of course we all know that in reality, 99.9% of usage is engagement spam.


What I'm saying is it's literally not possible to use them for a calendar app or a video calling app or anything along those lines. People simply won't get the notifications until ten minutes after the person called or the calendar event started. (No, it's not consistently 10 minutes, it's random, and can be several hours in the worst case, so you can't schedule the notification earlier to compensate in the calendar case).

If these things were possible then maybe people would see the benefit of web push. But spam is the only possible application right now, so spam is all you see. It's really unfortunate because there are many other legitimate uses that should be possible...


Let me add to this, they're also not possible to use without a serverside component. Using them for a calendar should be possible without a server, you should be able to just schedule a web notification locally. But you can't, you can only subscribe to a server.

I agree with this, Google made a system that's only good for spam, refuses to fix it or expand on it, and as a result everyone hates it.


A server component isn’t a surprise to me, as something needs to be sending the “push” to the client. It’s either your servers, or Apple and googles servers.

What I don’t fully understand about webpush, and the people trying to use it who are having issues, why not just use regular websockets/what is the difference between webpush and websockets. Both require a server, both require a persistent connection, both allow the server to “push” data to any client connected.

In my mind the “push” mechanism should be a system that isn’t constantly connected to a server, yet a server would still be able to route packets to a client where it wanted. Do our phones really have nonstop persistent connections to apns to get pushes? How could that run all the time and not kill batteries? Maybe I don’t know what webpush is even thought I’ve read about it lol


Websockets only work while your site is open in a tab and the tab is not frozen. Web Push works even when all browser windows are closed.


> Web Push works even when all browser windows are closed.

Well... "works" ;)

But that is the idea, and that is why a lot of developers were excited about web push. It says something about the state of web notifications that we all got excited about being given the opportunity to set up a remote server, track notification subscriptions, and manually trigger them via an HTTPS request. And yet, we did get excited about that; that was seen as an improvement.

And I guess the joke is on us for thinking that if we did all that the phone would finally actually show the user the notification reliably :)


> you should be able to just schedule a web notification locally. But you can't, you can only subscribe to a server.

This isn't entirely true; WebPush is server only, but the Notification API can be used locally. You could schedule a timeout that causes a notification, as long as the page stays open, and to do it while the page is closed you could use a ServiceWorker. Potentially a ServiceWorker may or may not stay active depending on the user's battery settings, but native notifications too can also be disabled by the user.


ServiceWorkers are subject to the same delay issues. In fact the ServiceWorker requirement is the whole reason for the issue in the first place: receiving a Web Push notification requires running a ServiceWorker and Android won't let it run in the background except at certain times. IMO the fix is to change the Web Push API so that you can send (or schedule ahead of time) notifications that can be displayed without activating the ServiceWorker. Alternative solutions would be for Android to relax the restrictions that prevent ServiceWorkers from running, or for Chrome to try to fit ServiceWorkers into the existing restrictions somehow. But for some reason Google refuses to try any of these, and so Web Push rots.


> but the Notification API can be used locally

The problem is that the notification API is next to useless. If I remember correctly, the uselessness of the notification API was one of the driving forces behind devs being so excited about web push. Finally we have a way to send notifications when the app is closed. Except... no, not really, because Google messed up that too.

I don't understand why it's so complicated to be able to just schedule a notification to go off at a specific time the same way that native notifications work, but apparently Google thinks that would be a horrible overreach of the web. Now Bluetooth and MIDI access on the other hand, they're fine with that. Google thinks that stuff is very good to have the web. Just don't let the user set alarms, that would be dangerous. /s

Snark aside, the short response is that I don't think this counts as "scheduling" -- scheduling is not "leave a process active and then manually fire the notification once you've personally checked that it needs to fire. And I have seen people try to get this working using background sync, push notifications, all kinds of nonsense. It's just bad design that people are even attempting to figure out those kinds of tricks. This is the kind of weird design that only makes sense when you remember that it came out of an advertising company.

> Potentially a ServiceWorker may or may not stay active depending on the user's battery settings, but native notifications too can also be disabled by the user.

The key difference is that if a user disables native notifications, it's because they want to. If a service worker closes, it's for some opaque reason that the user may not even be aware of. It's not user-controlled. User-controllable permissions are great. Android-controlled permissions that are opaque to the user and can't be overrided even for critical apps like alarms are less good.

Also, it's just wildly inefficient and clunky -- what we want out of notifications is not to run a background process, it's to schedule an event to happen at a specific time and to let the OS handle it. I don't want to be running code to make an alarm trigger, I want to update an event queue. Maybe I want the ability to run code in response to an event, but even that is less important than being able to say "please show the user this piece of text at 5:45 and give them a link to open the PWA."

Regardless, I shouldn't need a running service worker to tell the phone OS that in 30 minutes a notification should pop up.

----

What should happen is you schedule a notification with text and a timestamp, you get an ID back and put it in local storage, a UI is surfaced to the user by the OS that allows them to view notification access and upcoming notifications and set limits, and the app can use the returned ID if it's activated or syncing to edit the notification or remove it before it fires.

And ideally web push notifications would hook into that API. Maybe provide a way to respond to events or run code in response to the notification if you want to get fancy.

That would be the sensible, human way to design a notifications API if we were optimizing for user control, privacy, reliability, and developer ease of use instead of optimizing almost entirely for advertising and spamming people. At the very least you'd think users should have permissions and control over how notifications work instead of the phone just silently messing with things. Absolutely ludicrous that we've made an API that's so unreliable that it can't be used for timers, but also that doesn't have enough control to allow me as a user to filter notifications that apps send.


Yeah. I don’t know why browsers have them enabled by default. Banning web notifications in my browser is one of the first things I do whenever I set up a new machine. I don’t want every second shitty news site to show browser dialogs asking if the site can spam me, even when I’m not on the page. What a horrible experience and a horrible feature.


I’m not sure why Web Push is often singled out for this criticism, the same goes for app notifications.

I’ve never actually gone down the road of creating one but in theory you could make an almost entirely decentralized peer to peer messaging service with a PWA implementing the Web Push API to exchange messages. I agree that sadly most of the use cases are spammy nonsense but it remains an interesting API to me.


Why was the movement for push on ios then, if it never worked? Is it a kind of thing that everybody “wants” but no one buys?


> Why was the movement for push on ios then, if it never worked? Is it a kind of thing that everybody “wants” but no one buys?

It's the kind of thing that consumers want but corps don't as it allows individual app developers to easily self-host efficient realtime notification instead of being locked in to centralised proprietary services from Apple & Google.


Do consumers actually want it? This feels like developer projections.

The GP have a point: For years we heard that mobile web apps were almost there but for the laggard Apple (see all of the "Safari is the new IE" comments). The argument never made any sense given that Android hits monopoly levels in many areas, and has an enormous global base of over a billion users, yet mobile web apps see extraordinarily little uptake. But it was an argument nonetheless.

So now Apple made mobile web apps first class and implemented all of the must-haves and mobile web apps...still have negligible uptake. And the panacea platform still has critical defects that make it a subpar experience regardless. The new IE?


> Do consumers actually want it? This feels like developer projections.

Asking whether consumers want any developer API they clearly don't know exists is always tricky as is going to be a "want" by proxy. First and foremost, there's cost. Developers will pass on FCM service costs in app pricing which is clearly bad for consumers. Service choice encourages price competitiveness. But beyond that, in this case, I would also say that consumers installing a secure messaging client or non-Google email client likely don't want Google collecting metadata on all of their secure messages (& potentially actual data on their plaintext messages - regional legal compliance depending).

> For years we heard that mobile web apps were almost there but for the laggard Apple

Both Google and Apple each have their primary focus areas when it comes to marketing & propaganda - for Apple, its privacy (the justification for their walled gardens); for Google, they're pushing the web forward.

Neither are true. The reality Google have always been behind what's actually needed in implementing true PWAs (despite inventing the term) - calling out Apple was a distraction tactic. Google will only ever push PWAs to the point that they don't interfere with their adjacent revenue priorities. Which is often.

> The new IE?

Nothing new about it. Chrome has been the new IE almost since inception. Here's an entertaining sendup from 13 years ago, just 3 years after its inception - the parallel to Chrome was already obvious enough at the time to not even require mention: https://brucelawson.co.uk/2010/in-praise-of-ie6/


Does Apple's implementation have the same issues? I don't know.


It may, but since webpush never worked properly on android/chrome, the question arises who those people were (devs? users?) and what exactly they contrasted apple to when they accused it. Now it seems like apple implemented webpush, but no one really cared. Such nonsense.

Edit: I mean you still can’t go PWA-only because it only works on at most one of the two biggest platforms again. The only difference is that apple never hid its motives behind the fake tech.


What solution is there here? No one would suggest that letting every site set up a long-lived network connection would be a good idea. So you need a central trustworthy connection. If you don't trust the company that makes your browser/OS then why are you using it?


Does firefox suffer the same 10 min delay or does it work there?

I'm considering using it to give myself some notifications from my website.


I've implemented this and it works as expected in Firefox (no delay, notifications are 1 or 2 seconds of latency at most from send time).

Be ready to do lots of debugging to implement this though -- its far from straightforward and overly complicated IMO.


I didn’t know this. I always thought web push could mean no more need for apps?


How the push service delivers the message to the browser is still mysterious to me. Is Firefox simply hardcoded to poll Mozilla's push service?


Yes. Each browser vendor runs a push notification backend, where browsers automatically connect to. Each end user browser instance has a unique identifier with that push backend.

As a matter of fact, Mozilla's backend is even open source and written in rust:

https://github.com/mozilla-services/autopush-rs/

EDIT: And to send push notifications to an end user as a service provider, you (in simple terms) receive an encoded version of that URI from the push service, along with an authentication token that authorizes you to send notifications to the push service, which will be forwarded to the user that corresponds to the URI.


You can look at your registered service workers by going to about:debugging#/runtime/this-firefox You'll see the ones that can do push give you the URL, something like updates.push.services.mozilla.com/wpush/v2/...


I haven't looked into this at all, but for desktop I would expect the browser to maintain a WebSocket connection (for all websites) to the browser vendor's "push server", if WebSockets doesn't work for some reason, then it can fall back to long polling.

For mobile devices it's discouraged to maintain your own TCP connections for power usage reasons. So I would expect browser developers to have their mobile browsers use the mobile's native push service (e.g. for Android or iOS) to register for pushes, then the browser's backend push service sends push notifications via Apple/Google's push servers which in turn send it to mobile devices themselves.


If it's centralized at that level anyway, why can't Mozilla's push service also do some kind of spam filtering?


The payload of a web push message is always encrypted, iirc the API doesn't have any mechanism to send an unencrypted message.


Basically, yes.


I'm surprised to learn that this isn't an open standard. E.g I must make an API call to a browser vendor. Is this a form of vendor lock-in?


It’s an open standard but it’s centralized, and not all of it is covered by an open standard.

Here’s the page about browser support. https://github.com/web-push-libs/web-push/tree/master#browse...


Well, in the git repo, they directly link the RFC https://datatracker.ietf.org/doc/html/rfc8030


Wouldn't this be easier to maintain a websocket/socket.io type of connection with the web page? And just push new events from the server to the page directly?


That wouldn’t scale, and wouldn’t work if the page wasn’t open and active (e.g. suspended tabs, closed browser, etc)


It would open up a powerful new avenue for tracking users if every browser maintained a permanent, identifiable TCP connection, even when the page was closed, and kept it up as the user moves between wifi and mobile data.


That would waste battery and other resources having to keep a connection open to every possible site that could possibly send you a notification.


Is there a meaningful difference between waking up the CPU from sleep to maintain a single tcp connection vs waking it up to maintain 50? Provided of course all 50 require a keepalive packet at the same time, I don't think so. But feel free to correct me.


Yes, because the single connection to the push server is hard optimized to stay alive regardless of NAT etc. Cellular carriers have special handling for APNS and GCM, for example. (And I assume there's some kernel & firmware hacks in devices to further offload some handling of APNS/GCM protocol)


> Cellular carriers have special handling for APNS and GCM, for example

Would you have any extra info on this? Thanks!


Not off the top of my head, but I remember the iPhone in its early years required specific carrier support because of that permanent APNS connection. Can't find a source for this now but I remember that being one of the reasons that iPhone 2G/3G/3GS wouldn't work (well) on other carriers even after SIM unlocking.

I assume nowadays it's more to do with GCNAT pruning connections to APNS/GCM less heavily than other "regular" connections (which is doable given that APNS has specific ports[1]), or cell carriers having different routing & handling for push notifications IPs, but that's just speculation.

1: https://support.apple.com/en-us/102266


If you're like me you might want to take this as a push to disable all notifications in Firefox:

https://superuser.com/questions/1300131/how-to-completely-di...


It's a shame that some sites are abusing this potentially useful feature to try and increase engagement on their site.

The correct (IMO) way to use this is to request permission after a user initiates it. E.g. clicking a button somewhere in the UI that says "Enable notifications" whilst being in some context where it makes sense to potentially want to enable them.

This is how the web share API works. Calling `navigator.share()` without user interaction will fail as it requires "transient activation"[2]

[1]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_A... [2]: https://developer.mozilla.org/en-US/docs/Glossary/Transient_...


Firefox requires both that the user initiates the action that enables the push, and that the user then accepts to receive the notifications in a dialog from the browser itself.

That question is quite old. Nowadays nobody have that kind of problem.


yesn't social engineering and people not understanding anything about technology are a thing, I had to disable notifications for an older person before

but at least no one who potentially is on HN should have that problem ;=)


> It's a shame that some sites are abusing this potentially useful feature to try and increase engagement on their site.

First time on the internet?


Any browser feature that allows sites to pop up any sort of dialog will be used to harass people, usually for ads. That might as well be a law of the internet.


TL;DR: Settings -> Privacy and Security -> Notifications -> Block new requests asking to allow notifications


"You’ll receive an error if a user has revoked the notification permission on your page (or if the subscription has expired). You can catch these errors and remove invalid subscriptions."

From an outside perspective, this doesn't seem right -- wouldn't you want to check the error is because the channel has been revoked? It could be due to a temporary outage on either your side or the push server itself. With the code above, you might end up revoking all of your push subscriptions (upon broadcast) if your network goes down.


I have written one blog introducing Web Push Notifications on iOS

https://taoshu.in/web/push-on-ios.html


Good article. Another VAPID key generator site is helpful, too bad it doesn't seem to work. And even when you have what seems like a valid key, browsers might give errors of the form "Invalid VAPID token" which are very frustrating... And sometimes only happen in Firefox vs Chrome. Would like to see anyone do a more thorough write-up of this part though:

> In order to send web push notifications from your backend application server, you have to construct, encode, and encrypt the messages properly.

Basically, that's the hardest part, if you don't have library support of someone having done it for you already.

Web Push is both simple in design and yet frustrating. I gained some sympathy for sites that have opted not to support it after trying to do it myself without a library on a test page. (I'd only do it for real if anyone besides myself would use it, and just use the library.)


Great article, thank you for sharing! The web-push package has a generateVAPIDKeys have you tried that? Was it not good since you use vapidkeys.com?


Thanks! I didn't realize web-push had a way to generate the keys until later. Also it was just easier to use the vapidkeys site.


vapidkeys.com signs you up for their newsletter I later found


> npx web-push generate-vapid-keys --json > vapid.json

Does the trick


I do like Web Push Notifications.

But the way chrome implemented them on Windows makes them the perfect tool for social engineering, sneaking advertisement into windows and other malicious use cases.

Worse the controls for disabling them had been a complete UX nightmare last time I took a look at it (both in FF and Chrome; nightmare as in inexperienced users will have issues doing so) making it even more perfect for abuse.

And instead of fixing that Google decided to make it semi unusable for many proper use-cases (and FF didn't fix that either).

To top that off last time I tried to use them they didn't work on Firefox no idea if that was my firewall, uBlock, Firefox or the websites fault.


I wrote my own push notification in PHP using Server Sent Events.

Basically it looks on the database for notifications not sent that are new and then send them.

You need to have your browser running in the background but it worked fine for me.

Never tested it in large scale though.

https://youtu.be/D4wimodtpKk


Srs question, does anyone actually use these?


Yes.

I maintain an online forum. We used to have an app, but maintaining it was too expensive. I wanted push notifications, so I added notifications via web push. I’ve got a few hundred signups for the feature, so you can see the scale of our operation doesn’t justify both a mobile app and website.

Worst part is that it still requires installing the site as a web app on iOS.


Some chat apps use them. I think uptake has been slow because safari was very late to the party


I think uptake is slow because no one uses them nor wants them.


No one uses them because they don't work


Chicken or egg? They don't work because no one wants to put forth resources to fix it, because we're already inundated with notifications everywhere else. Email is fine.


I do.


Sad state of PWA: we can send messages to thousands of browsers, but still cannot fire single local alarm on local device which is offline.


great / detailed write-up OP. hat-tip


Thanks :)


That is actually pretty cool.

But no, I have that turned off. I've never seen a purpose beyond spam.


I used it with FF mobile.

As FF ask you to confirm in a FF controlled dialog there is no risk for spam.

At the same time it allowed me to get notifications for a site like with an app without needing to install any app.

And at least on FF mobile it was also always clear where the notification is coming, in difference to Windows+Chrome where I had to help an older person to fix an ad problem and it took me an embarrassing long time to realize where the ad is coming from.


Strange, browser tells me domain pqvst.com does not exists



Huh. What browser?


Firefox, but it works fine now…


"While you can technically generate your VAPID keys by yourself, it is much easier to use a generator, like vapidkeys.com, which will generate a set of keys for you."

Please don't use online tools to generate private keys. Not CSRs, not WG configs or bitcoin wallets, Nothing. Just don't.


Yes. That is a good point. I'll update the post and recommend using a local tool instead.


Hm, it looks like all Chromium-based browsers, including Edge, Brave, and Samsung Internet, use Google’s endpoint for web push subscriptions. Is that true? If yes, is that a potential privacy issue?


Edge uses Microsoft push servers. The endpoint is on "[...].notify.windows.com".




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: