Web Push Arrives in Firefox 44

Have you ever wished that a website could notify you when something important happened, even if you didn’t have the site open? Maybe you’ve got an incoming WebRTC call, an instant message, or a financial update. Perhaps your city just declared an emergency snow plowing schedule.

Sometimes you just want to know when something happens.

That’s what Web Push does. It’s available now in Firefox 44.

What does Web Push look like?

As long as your browser is running, it can receive notifications from websites, even without having that site open. This means you can close your email tab and still find out when a new message arrives. That’s a huge win for memory usage, performance, and battery life.

Notifications from websites are indistinguishable from native notifications, and Mozilla’s Service Worker Cookbook has several live demos where you can see this for yourself.

Screenshot of a Push Notification on Mac OS X

Much like with geolocation or webcam access, Web Push requires explicit, revokable permission before a website can show notifications to a user.

Screenshot of the in-browser Push Notification permissions prompt

What about privacy?

Web Push works by maintaining a persistent connection to a Push Service that acts like a central relay for messages. Each browser vendor runs their own Push Service, and it’s been designed to safeguard your privacy:

  1. To prevent cross-site correlations, every website receives a different, anonymous Web Push identifier for your browser.
  2. To thwart eavesdropping, payloads are encrypted to a public / private keypair held only by your browser.
  3. Firefox only connects to the Push Service if you have an active Web Push subscription. This could be to a website, or to a browser feature like Firefox Hello or Firefox Sync.

You’re always in control: Push notifications are opt-in, and you can revoke permission from any website at any time, either from the page info panel or from the “Notifications” section in Preferences ? Content.

How does Web Push work?

Before today, people had to rely on apps, emails, or text messages for timely notifications. Now the Web can do that.

Web Push is an extension to the Service Worker standard, which means you can find excellent, annotated demos of Web Push in Mozilla’s Service Worker Cookbook. MDN also has great documentation on Web Push, and if you need to go straight to the source, the most recent Editor’s Draft of the specification lives on GitHub.

Last October, Chris Mills wrote an excellent introduction to Web Push here on Hacks, which explains the Service Worker lifecycle and how it relates to Push. To recap:

  1. A website registers a Service Worker with the browser. Service Workers are small JavaScript programs with super powers like intercepting network requests or running even when their parent website is closed.
  2. The Service Worker registration object exposes a pushManager property.
  3. The website uses the pushManager to either get an existing subscription or create a new one
  4. The subscription object exposes metadata about the subscription, including a unique endpoint URL on your browser vendor’s Push Service.

Whenever the website POSTs to that endpoint, the Push Service routes the message to your browser, where the appropriate Service Worker receives a push event. The Service Worker can then show a notification or take other actions.

In code, the Service Worker might look like this:

self.addEventListener('push', function(event) {
  event.waitUntil(
    self.registration.showNotification('Example Notification', {
      body: 'Hello, world!',
    })
  );
})

Meanwhile, registering the Service Worker and getting permission to show notifications might look a bit like the code below.

Note: This code sample uses ES7’s draft async/await syntax, since it reads most clearly. To use this in production, check out the equivalent in plain JavaScript.

async function registerForPush() {
  // Register the Service Worker
  let registration = await navigator.serviceWorker.register('service-worker.js');
  
  // Check if we already have a subscription
  let subscription = await registration.pushManager.getSubscription();
  
  // If not, try to subscribe.
  if (!subscription) {
    subscription = await registration.pushManager.subscribe();
  }
  
  // Save the subscription data on our website's backend.  
  await fetch('/save-push-endpoint', {
    method: 'post',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(subscription)
  });
  
  // Done! Now our backend can send Push messages by POSTing to subscription.endpoint!
}

Again, there are a bunch of live demos with annotated source code over at the Service Worker Cookbook. If you’re confused, start by reading those.

Other Questions

Will a user’s endpoint URL ever change?

The endpoint can change at any time. In practice, this should be rare, but you should always be prepared to handle a pushsubscriptionchange event, and should check for a new endpoint whenever you getSubscription() or subscribe().

What’s the state of browser support?

At the time of writing, Push works in Firefox for Desktop and has partial support in Chrome. Pushing to Chrome also requires some additional setup. The Microsoft Edge team lists Push as Under Consideration. More info at Can I Use?

How do I let a user unsubscribe from Push?

Use the subscription.unsubscribe() method. Don’t forget to also update your backend so you stop sending notifications to the old endpoint.

Can I check if subscribe() will prompt the user, before it actually happens?

Yep! Calling pushManager.permissionState() returns a Promise that resolves to your current permission state: "granted", "denied", or "prompt".

Make sure to let us know what you think about the Push API in the comments. We welcome all feedback including suggestions, questions, and bug reports.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)
Tagged on: , ,

8 thoughts on “Web Push Arrives in Firefox 44

  1. David Piepgrass

    I was shocked by how this feature behaved in Chrome, and users of Firefox are in for a similar surprise. The problem is that there is NO INDICATION that you can receive “notifications” from a web site that isn’t open in your browser.

    Sure, when the Facebook tab was open it asked me if I wanted “notifications” and I said “sure!” It never crossed my mind that I’d still get “notifications” AFTER I CLOSED THE TAB.

    WHY doesn’t Firefox mention that notifications will be received even when the site is closed? Will notifications still be received when ALL tabs are closed? Don’t give ME the answer: change the UI and give USERS the answer.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  2. Bob

    I guess Netscape just couldn’t stand to let Netscape Netcaster rest in peace.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  3. Dan Callahan

    Right now, user-visible settings are on a per-origin basis. E.g., you can dismiss prompts with “never ask me again [on this site].” If you want to turn Push off altogether, toggle dom.push.enabled in about:config.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  4. g

    I do suppose there will be a configuration item to unconditionally turn this crap off, right?

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  5. Jesus Perales

    This implementation is compatible with web push for Firefox OS ?

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  6. Dan Callahan

    Our production Push Server is written in PyPy, and can be found at https://github.com/mozilla-services/autopush. From what I recall, the main concern is memory overhead per connection, since the service has to maintain an enormous number of websocket connections, the majority of which are idle at any given time.

    Self-hosting isn’t necessarily supported, but it’s not impossible. Once you have another service up and running, you’d just have to change dom.push.serverURL in about:config.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  7. Valentin

    I wonder… What are the requirements for the Push Server ? Isn’t it a (extremely) huge database ? And as a user, can I choose another push server ?

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)

Leave a Reply