40

I'm using the HTML5 notification API to notify the user in Chrome or Firefox. On desktop browsers, it works. However in Chrome 42 for Android, the permission is requested but the notification itself is not displayed.

The request code, works on all devices:

if ('Notification' in window) {
  Notification.requestPermission();
}

The sending code, works on desktop browser but not on mobile:

if ('Notification' in window) {
  new Notification('Notify you');
}
sideshowbarker
  • 62,215
  • 21
  • 143
  • 153
Jorn
  • 16,599
  • 15
  • 67
  • 103
  • 1
    I'm having the exact same problem. Also tried `window.webkitNotification`. *Push notifications*, on the other hand, work but are a different beast altogether: https://developers.google.com/web/updates/2015/03/push-notificatons-on-the-open-web?hl=en (demo https://simple-push-demo.appspot.com/ ) – BoppreH Aug 02 '15 at 06:02

4 Answers4

53

Try the following:

navigator.serviceWorker.register('sw.js');
Notification.requestPermission(function(result) {
  if (result === 'granted') {
    navigator.serviceWorker.ready.then(function(registration) {
      registration.showNotification('Notification with ServiceWorker');
    });
  }
});

That should work on Android both in Chrome and in Firefox (and on iOS in Safari, too).

(The sw.js file can just be a zero-byte file.)

One caveat is that you must run it from a secure origin (an https URL, not an http URL).

See https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification.

sideshowbarker
  • 62,215
  • 21
  • 143
  • 153
  • 1
    This works, but creates a background ServiceWorker with its own lifecycle. I wish there was a more lightweight solution, but oh well. Thanks for the throughout answer. – BoppreH Aug 06 '15 at 00:22
  • 3
    Regarding having a more lightweight solution (that doesn’t require ServiceWorker), I recommend taking time to raise an issue at https://github.com/whatwg/notifications/issues. The people very much want feedback from real-world web developers, and in my experience they’ll highly responsive to feedback they get. But without anybody sending feedback, it’s much less likely there will be any change. – sideshowbarker Aug 07 '15 at 01:34
  • 5
    The proposed solution will not handle click events though which is probably the same reason why the light API is not available in Android. There is no guarantee that the page will be around by the time the notification is clicked (since it can be killed by the memory manager at any point) so this would result in a super flaky API. – Miguel Garcia Oct 17 '16 at 11:06
  • Hi, I keep getting this error message: _"failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR"_ and the socket object creation is shown as the error origin _[websocket = new WebSocket("wss://www2.demo.domainname.com:45786/directory/socket.php");]_ . 45786 is the port number I used in the non-ssl version, and it worked fine. Replacing that with 443 or taking it off altogether does nothing either. Would you have any suggestions for a fix please? – Ashil John Apr 11 '17 at 08:32
  • Where I can get `sw.js` file? – Encrypted Mar 05 '21 at 21:29
4

Running this code:

 if ('Notification' in window) {
  Notification.requestPermission();
}

Console in Chrome DevTools shows this error:

Uncaught TypeError: Failed to construct ‘Notification’: Illegal constructor. Use ServiceWorkerRegistration.showNotification() instead

A better approach might be:

function isNewNotificationSupported() {  
    if (!window.Notification || !Notification.requestPermission)  
        return false;  
    if (Notification.permission == 'granted')  
        throw new Error('You must only call this \*before\* calling 
Notification.requestPermission(), otherwise this feature detect would bug the 
user with an actual notification!');  
    try {  
        new Notification('');  
    } catch (e) {  
        if (e.name == 'TypeError')  
            return false;  
    }  
    return true;  
}

Function Source: HTML5Rocks

Kalimah
  • 10,305
  • 11
  • 38
  • 78
4

If you already have a service worker registered, use this:

navigator.serviceWorker.getRegistrations().then(function(registrations) {
  registrations[0].showNotification(title, options);
});
Ben
  • 899
  • 8
  • 11
2

I had no trouble with the Notification API on Windows Desktop. It even worked without issues on Mobile FF. I found documentation that seemed to indicate Chrome for Android was supported too, but it didn't work for me. I really wanted to prove the API could work for me on my current (2019) version of Chrome (70) for Android. After much investigation, I can easily see why many people have had mixed results. The answer above simply didn't work for me when I pasted it into a barebones page, but I discovered why. According to the Chrome debugger, the Notification API is only allowed in response to a user gesture. That means that you can't simply invoke the notification when the document loads. Rather, you have to invoke the code in response to user interactivity like a click.

So, here is a barebones and complete solution proving that you can get notifications to work on current (2019) Chrome for Android (Note: I used jQuery simply for brevity):

<html>

<head>
<script type="text/javascript" src="libs/jquery/jquery-1.12.4.min.js"></script>
<script>

$( function()
{
    navigator.serviceWorker.register('sw.js');

    $( "#mynotify" ).click( function()
    {
        Notification.requestPermission().then( function( permission )
        {
            if ( permission != "granted" )
            {
                alert( "Notification failed!" );
                return;
            }

            navigator.serviceWorker.ready.then( function( registration )
            {
                registration.showNotification( "Hello world", { body:"Here is the body!" } );
            } );

        } );
    } );
} );

</script>

</head>

<body>
<input id="mynotify" type="button" value="Trigger Notification" />
</body>

</html>

In summary, the important things to know about notifications on current (2019) Chrome for Android:

  1. Must be using HTTPS
  2. Must use Notification API in response to user interactivity
  3. Must use Notification API to request permission for notifications
  4. Must use ServiceWorker API to trigger the actual notification
Jeff Bruce
  • 41
  • 2
  • Is there a way to check for existing permissions with service workers? Something like `if (Notification.permission === "granted") {...}`? – Roy Prins Jan 17 '19 at 13:51
  • 1
    Actually, you use the Notification API to check for existing permissions exactly as you described. What makes Chrome for Android unique is that the Notification API currently doesn't work to create the actual notification. But it does work to check for permissions and for requesting permission. Once you have permission, you then use the ServiceWorker API to actually cause a notification to be shown. – Jeff Bruce Jan 17 '19 at 19:11
  • 1
    Didn't work for me. @Ben's answer with `registrations[0]` worked. – user66081 May 11 '19 at 01:44
  • 1
    Did not work for me in Chrome on Ubuntu desktop nor in Android. – gene May 14 '19 at 08:47