mozilla
Your Search Results

    Notifying users via the Notification and Vibration APIs

    This article is in need of a technical review.

    This article follows on from the previous one, Checking when a deadline is due, looking at how we can actually provide users with a system notification using the Notification and Vibration APIs.

    App recap!

    In case you didn't read the previous article, here is a quick recap on the sample app we're looking at. We're looking at To-do list notifications, a simple to-do list application that stores task titles and deadline times and dates using IndexedDB, and then provides users with notifications when deadline dates are reached, making use of the Notification and Vibration APIs. You can download the To-do list notifications app from github and play around with the source code, or view the app running live.

    This app works well on Firefox, Firefox OS, and Internet Explorer 10, sort of works (with a bug) on Chrome and Opera, and also contains install code so that it can be installed on Firefox and Firefox OS.

    Triggering a system notification

    The Notification API is a small, simple object that lets you make a system notification appear. You can specify the notification title, a custom icon to appear along with the notification, and metadata such as an identifying tag and body text to be displayed under the title. It also provides event handlers to detect when the notification has opened, been clicked on or closed by the user, or failed to display for some reason. The notification will always display as soon as it is called, so it is up to you to program the timing of the notification, hence all our work in the Checking when a deadline is due article.

    In our sample app, the createNotification() function is called when the program detects that a deadline is up. Let's walk through the code now:

      function createNotification(title) {
        if (!"Notification" in window) {
          console.log("This browser does not support notifications");
        }

    First of all we put in a simple check to see if the current browser supports the notifications API. We'll just log it to the console for now, rather than screaming at the user — the app is still useful without the notifications, although obviously having the notifications increases the app's usefulness.

        else if (Notification.permission === "granted") {
          // If it's okay let's create a notification
          var notification = new Notification('HEY! Your task "' + title + '" is now overdue.');
        }

    Next we check whether the app has permission to generate a system notification by querying the Notification.permission property. This is a permission granted by the user, which can take one of three settings:

    • granted: The user has explicity allowed the app to generate system notifications.
    • denied: The user has explicitly denied the app permission to generate system notifications.
    • unknown: The app doesn't know what permission to user has granted it yet, so by default it acts like permission is denied.

    If permission is granted, we create a new notification, which displays a message letting the user know their task is overdue. This includes the title of the task, which we received as an argument into the createNotification() function (this is taken from the data stored in IndexedDB).

        else if (Notification.permission !== 'denied') {
          Notification.requestPermission(function (permission) {

    If the permission hasn't been granted, we now check that the permission isn't explicitly denied. If not, we use the Notification.requestPermission() method to ask the user whether it is okay to generate a system notification. This will differ by system, but will generally appear as some kind of modal dialog.

            if(!('permission' in Notification)) {
              Notification.permission = permission;
            }

    When the permission has been set, we first make sure Chrome/Opera will store the permission choice for future notification attempts. This is a known issue.

           if (permission === "granted") {
              var notification = new Notification('HEY! Your task "' + title + '" is now overdue.');
            }
          });
        }
      }

    The final part of the code checks whether the user granted permission in response to the Notification.requestPermission() call, and if so generates a notification, just like the earlier code did.

    The code above provides us with a notification, when a task deadline is reached (the images below show Mac OSX, Android, and Firefox OS):

    Screenshot of an Android phone showing a notification bearing the message Hey, your task test is now overdue.

    Screenshot of an Android phone showing a notification bearing the message Hey, your task bury gran...

    Screenshot of a Firefox OS phone showing a notification bearing the message Hey, your task catch elephant is overdue

    Notification body text

    Okay, so the notification works. But it isn't great right now. The above screenshots show that some of the text is cut off in the notification title, so it is quite hard to read, at least on some systems. To improve this, we can separate the text shown in the notification into a heading and body text.

    To do this, we need to use the Notification.body property, which can be specified inside the options object when creating the notification, like so:

    var notification = new Notification('To do list', { body: text });

    This just replaces the var notification ... line we saw earlier; you'll also notice that I've replaced the title text with something shorter that is less likely to be truncated. We need to replace text with a string containing the actual body text. We could put it directly inside the object, but it is neater and more flexible to put it inside a variable:

    var text = 'HEY! Your task "' + title + '" is now overdue.';
    var notification = new Notification('To do list', { body: text });

    And there you go. Now our application gives us a neater notification containing title and body text:

    Screenshot of an Android phone showing a notification with a header message plus a portion of body text.

    Notification icons

    You can go one further and include a custom icon inside your notification, replacing the default system notification icon (some platforms show nothing by default) with an icon of your own choosing. This is as simple as adding another property, icon, to the notification options:

    var img = '/to-do-notifications/img/icon-128.png';
    var text = 'HEY! Your task "' + title + '" is now overdue.';
    var notification = new Notification('To do list', { body: text, icon: img });

    Here's the result:

    Mac OSX screenshot showing a notification with a header message plus a portion of body text and a custom icon.

    Note the URL provided to for the icon has to be a relative path from the origin of the app's install URL (or the root of the zip archive, in the case of packaged apps).

    Good vibrations

    Notifications are great, but what if you are not looking at your phone, have the volume turned off, have it in your pocket, etc.? A great complement to a notification to improve discoverability is a short burst of vibration from the device. Vibration hardware is very common in handheld devices these days, and it's no surprise that we've come up with an API to control this from the Web.

    The Vibration API is incredibly simple. At its core there is only a single method, which allows you to specify how many milliseconds the device should vibrate for. This is very simple to slot into our notification code:

    var img = '/to-do-notifications/img/icon-128.png';
    var text = 'HEY! Your task "' + title + '" is now overdue.';
    var notification = new Notification('To do list', { body: text, icon: img });
    
    window.navigator.vibrate(500);

    A notification is now accompanied by a half-second burst of vibration.

    You can optionally include a series of millisecond values if you want to trigger a series of vibrations with pauses in between:

    window.navigator.vibrate([1000, 500, 1000, 500, 1000]);

    Values alternate between a vibration, then a pause, then a vibration, etc. So the above values equate to three vibrations of one second each, with a half second pause in between them.

    Permissions for Notification API

    Please note that while the Notification API is not privileged or certified, you should still include an entry in your manifest.webapp file when including it in an installable open Web app:

    "permissions": {
      "desktop-notification": {
        "description": "Needed for creating system notifications."
      }
    }

    Cross browser support

    The notifications and vibrations currently work on Firefox desktop/Android, Firefox OS, Chrome, and Safari, however work is going on to standardize these in the W3C, and we hope that other browsers and platforms will follow suit in supporting these rather useful APIs.

    For the benefit of browsers that do not support these APIs, we started off our createNotification() function with a condition block that checks whether Notifications are supported before continuing:

    if (!"Notification" in window) {
      console.log("This browser does not support notifications.");
    }

    This means that non-supporting browsers can still run the app successfully, although the notifications will just not work. We did think about providing a simple fallback notification such as an alert(), but we decided not to, as this is possibly a worse user experience than no notifications at all. The user needs to be looking at the browser at the time it happens for this to be useful, whereas system notifications will still be displayed even when the browser is not running in the foreground.

    Document Tags and Contributors

    Contributors to this page: Sheppy, chrisdavidmills
    Last updated by: chrisdavidmills,