Friday, April 26, 2013

Push notifications for the Open Web

I’m excited to announce a new WebAPI that Mozilla has been working on for the past few months – Push Notifications for Web applications. Push Notifications let web applications be notified that something has changed on the server and that the application should refresh its data. For example, a calendar application can use Push Notifications such that whenever a new event is added on the server, the calendar application gets started in the background. The calendar app would then add the event to its local agenda and shut down, all without the user’s intervention. When the (pleasantly surprised) user looks at his phone, it has a current copy of his agenda.
Thanks to Push Notifications, Web applications are freed from repeatedly polling for updates, leading to a better experience for everybody. Users get better battery life and more responsive applications. Developers don’t have to re-implement polling logic in every application they write. Mobile devices benefit from intelligent scheduling of notifications to reduce network usage and further improve battery life.
There were several challenges involved in making a push notification system for the open Web:
  1. Developers shouldn’t have to pre-register their applications with a push notification provider. Native app ecosystems require this; for example, you have to get a token from Google to use Cloud Messaging for Android. But for Web apps, which can be self-hosted instead of being distributed by an app store, such restrictions would only limit the audience. In addition, anybody should be free to run their own push server for their devices. Mozilla can run a server for Firefox users. Carriers can run their own servers, on which they can use cellular infrastructure to wake up Firefox OS devices. In fact, an individual user can even run their own push server if they choose.
  2. Users shouldn’t have to log in to a third party to use push capabilities. Note: Users may still need to log in to the app so the app knows what information to push to the device. For example an email app isn’t very useful without logging in.
  3. Protect the user’s privacy. This means that the push server should not receive any private or user-identifying information that is specific to the application. In keeping with this, the push server does not receive any application-specific data. It can only act as a “shoulder tap” or carry a number specifying a “version” or similar identifier.
  4. Make Push Notifications an application wakeup API and not a “user notification” API. The act of displaying a badge or popup notification is not covered by Push Notifications. This decoupling means that applications can use push for all types of tasks, from dealing with IM updates to syncing information across devices without interrupting the user. Applications that do need to notify the user can do so by using the Notifications API with Push.
We believe we now have a system that can satisfy the goals while still being secure and scalable.

How do I make my Web application push enabled?

It is very simple for web applications to use Push Notifications. In fact, in only about 100 lines of code, I modified Gaia to support “Push To Install”. Once you’ve logged in using Persona on your phone, you can install an application to your phone from any browser on any device, just by pushing it to the phone.
The basic flow for Web application developers is:
  1. Your application calls navigator.push.register() to acquire a unique URL, called a push endpoint. This endpoint usually refers to a push server. Your app can call register() multiple times for different uses. For example, an email application could have one push endpoint for every account it tracks.
  2. Your application uses something like XMLHttpRequest to notify your application server of this push endpoint. The application server is maintained by the application developer. For example, if you write a microblogging application, you will have a server where posts are aggregated. You would then associate the push endpoint with the particular user of your application.
  3. When your application server believes something interesting has happened that your application should be notified about, it makes an HTTP PUT request to the push endpoint.
  4. The push server and the user agent (Web browser/Web runtime/Firefox OS device) communicate and deliver a notification to your application. If your application is not running, it will be started in the background and receive the notification. The notification is delivered using System Messages.
  5. When it receives a notification, your application should connect to the application server and download the newest data. Since Push Notifications is a signaling system, it does not carry data in the notification.
I’ll do a blog post with a detailed Push Notifications tutorial soon.

Status

On March 28, 2013 the first pieces of code to enable Push Notifications landed on mozilla-central and are enabled for Firefox OS builds. Set the pref services.push.serverURL to wss://www.simple-push.com:9999 and the APIs should be available. You can also run your own server.
The protocol is unlikely to change, but client bugs are still being fixed. As such, this is an experimental API. Push Notifications also obsoletes the older Push Notifications API.
Push Notifications is only available to Web applications at this point. There is agreement that web pages loaded in tabs should also be able to use the API, but various technical issues need to be resolved before this can work properly. This is the next major issue the team will address.

23 comments:

  1. So you have 3 things: the application, the push endpoint, and the application server, right? what would be the application server in the example of the email app or a micro blogging app?

    ReplyDelete
  2. Wonderful news. A few queries though with regards to its implementation in B2G, if you could shed some more light -

    1. Will there be a way to achieve a two-way interaction, something like a "call to action" that the user can initiate inherent to push notifications? We have SMSs (just an example) create seamless two-way interactions, will there be scope for the same here?

    2. How do you think would abuse of this feature be addressed? Push notifications are more direct and upfront - most cases they simply pop-up someplace on your screen. Of course that can be circumvented via GUI modifications, but wouldn't it be a turn-off and cause users to move away from brands employing the technique?

    ReplyDelete
    Replies
    1. Oops, I intended to reply to you, but didn't get it right. My reply is below.

      Delete
    2. 1) Push notifications have a very restricted set of features, which is to wake up an app when something of interest happens on a remote server, and run a specific JS function within that app. The app is free to do whatever it wishes when it receives said notification, bound of course by other rules FxOS puts on the app. So an IM app could easily pop up the chat dialogue or send messages.

      2) It is up to the app to annoy the user by popping up a notification when it receives a push. As point 4 states, Push is not a "user notification" system. That said, before this is enabled, the Gaia team will work on an interface to disable push notifications for an app. Of course, subjectively, I would immediately uninstall any app that spammed me :)

      Delete
  3. I'm not a developer, but I'll give input from my understanding of things.
    1) This Push Notifications API is a way to wake up the app/page - not even send data (like a text message) to it. Once awoken, the app will then contact its server for the latest relevant data. So in the case of SMS, the app will contact its server in its own way (perhaps https for security) and download what's new and can then, if it wants, notify the user via the Notification API (*different from Push Notification*).

    2) As I mentioned above, the Push Notifications API and Notifications API are separate. Push does not interact with the user at all. Like with other sensitive APIs, desktop Firefox keeps a list of permissions for location sharing, notifications, etc, in the Page info dialog. But for any app or page that wants to send you notifications, you should be prompted to allow it on install. I don't know if Firefox for Android or FxOS have the permissions dialog yet, but if not they will.
    So an app/page has to ask permission first, but if they should abuse notifications, the user can disable that app's ability.
    I think, with the new addition of Notifications, Firefox *should* (hopefully will) be adding a Notification Center to all its browsers (and OS). This would make for a simple way for users to manage notification permissions in a central place. I know iOS has this.

    If I got anything wrong Nikhil (or anyone), please feel free to correct me.

    ReplyDelete
    Replies
    1. When I said "Notification Center" I meant it in the sense of a management interface for app notification permissions. In iOS it's a place where the most recent notifications reside.

      Delete
    2. Point 1 is correct, no data.

      For 2, again yes such a system will be in place eventually. I guess the toggle to disable push will likely be in the "App Permissions" page in Settings, but that is something the UX team will make a call on.

      Delete
    3. Exactly my thoughts, which is why the risk of this feature being abused more than ever comes to the fore. Developers act nice initially with their push messages, but a month down the line they will keep pestering you to no ends ^^

      Another thing I would probably think towards is the effect of wakelocks on devices having push notifications enabled. Your thoughts?

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. I have an iPhone and when an app sends me notifications I don't want (perhaps it's a game or something else I'd like to keep around) I just pop into the notifications manager and cut all its permissions. Then I never hear from it again but can still use it fine.
      I'm quite happy with the arrangement.

      (iOS has a surprisingly powerful control over the different types of notifications that apps are allowed)

      Delete
  5. power management is something we're looking at. there is no wake lock held but this does mean that there is a compromise between the instantaneous of notifications vs power consumption. on stable networks there is less of a problem since the CPU goes to sleep until interrupted by the nic. but ensuring that the connection is up does require the cpu to wake up occasionally. there isn't a lot of open prior art and data on push, so we're finding things out as we go.

    ReplyDelete
  6. I have a lot of questions about the background loading of these pages, in particular when an app isn't currently loaded. What URL is loaded? What if the user had closed the application, then opened it one or two more times in different tabs? Does an application know if it is loaded in the background, and thus able to respond to push notifications differently?

    ReplyDelete
    Replies
    1. @Calvin: I'm not sure what you mean by tabs, since a web app can have only one instance of it running. When an app isn't currently running, the app is started. That is what the system messages API does. The URL (relative to the app) to be loaded is specified in the manifest. I'm not sure if there is some API for an app to check if it has focus or not. Please try asking on #b2g or the mailing list.

      Delete
  7. do you know if this is coming to Firefox OS Simulator in Firefox Desktop any time soon?

    ReplyDelete
    Replies
    1. The code is there, you just need to set the two prefs services.push.enabled = true and services.push.serverURL = wss://nikhilism.com:9082

      Delete
    2. Hi,

      How do I change these settings? Do I need to patch my simulator/device or can I do it only within my app bundle?

      Delete
  8. Can I try the push notifications in Simulators ? Will it works ?

    ReplyDelete
  9. can this be used to awaken an app when near a location ?

    ReplyDelete
    Replies
    1. You could write an app which constantly monitored the location and sent it to a server. But then you wouldn't need push.

      Delete
    2. Sounds like what you're describing is a sort of location service in which the system/browser manages waking the app based on certain location-based criteria.
      Is that what you're thinking? If so Push notifications won't suit the bill.
      I'm unsure if that's something Mozilla has on its radar right now or not (or if this is a concept that's feasible without killing the battery).

      Delete
  10. I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post, Good luck!!!Charleston Mobile App

    ReplyDelete
  11. Found your blog post and thought you might be able to help. I was trying to get Simple Push working for my Firefox OS app and successfully received an endpoint (on Keon running 1.1). The problem I'm experiencing is that the system message is only delivered if the app is running. If it isn't, the the app isn't started. Do you happen to know what the issue could be?

    ReplyDelete
  12. Is it something like a ParseDB or an Urban Airship for the Web?

    ReplyDelete