228

I have been reading for past few hours about Push Notification API and Web Notification API. I also discovered that Google & Apple gives push notification service for free via GCM and APNS respectively.

I am trying to understand if we can implement push notification to browsers using Desktop Notification, which I believe is what Web Notification API does. I saw a google documentation on how this can be done for Chrome here & here.

Now what am still not able to understand is:

  1. Can we use GCM/APNS to send push notification to all Web Browsers including Firefox & Safari?
  2. If not via GCM can we have our own back-end to do the same?

I believe all these answered in one answer can help a lot of people who are having similar confusions.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
esafwan
  • 17,311
  • 33
  • 107
  • 166
  • sure, you can run your own backend, but it's complicated. – dandavis Nov 18 '15 at 03:54
  • 5
    It is not complicated much. [browser-push](https://lahiiru.github.io/browser-push) is a complete example tutorial on how to send push notifications to browsers without third party service. https://lahiiru.github.io/browser-push – TRiNE Jan 19 '17 at 03:37

10 Answers10

225

So here I am answering my own question. I have got answers to all my queries from people who have build push notification services in the past.

Update (May 2022): Here is a doc on web push notification from Google.

See this detailed introduction to notification API from Mozilla.

Airships article on the topic and how web push & app push varies.

Answer to the original questions asked 6 years ago:

  1. Can we use GCM/APNS to send push notification to all Web Browsers including Firefox & Safari?

Answer: Google has deprecated GCM as of April 2018. You can now use Firebase Cloud Messaging (FCM). This supports all platforms including web browsers.

  1. If not via GCM can we have our own back-end to do the same?

Answer: Yes, push notification can be sent from our own back-end. Support for the same has come to all major browsers.

Check this codelab from Google to better understand the implementation.

Some Tutorials:

  • Implementing push notification in Django Here.
  • Using flask to send push notification Here & Here.
  • Sending push notifcaiton from Nodejs Here
  • Sending push notification using php Here & Here
  • Sending push notification from Wordpress. Here & Here
  • Sending push notification from Drupal. Here

Implementing own backend in various programming languages.:

Further Readings:

Are there any free services to do the same? There are some companies that provide a similar solution in free, freemium and paid models. Am listing few below:

  1. https://onesignal.com/ (Free | Support all platforms)
  2. https://firebase.google.com/products/cloud-messaging/ (Free)
  3. https://clevertap.com/ (Has free plan)
  4. https://goroost.com/

Note: When choosing a free service remember to read the TOS. Free services often work by collecting user data for various purposes including analytics.

Apart from that, you need to have HTTPS to send push notifications. However, you can get https freely via letsencrypt.org

esafwan
  • 17,311
  • 33
  • 107
  • 166
  • 1
    You can use the Push API, each browser provides its own service. – Marco Castelluccio Jan 20 '16 at 13:36
  • 2
    You need HTTPS only for the Push API, not for Safari – collimarco Mar 21 '16 at 11:02
  • 5
    `onesignal`, nice info :3 – Kokizzu Jun 04 '16 at 13:25
  • 4
    Incase you don't wish to pay 3rd party libraries, here's a developer guide of writing this yourself. http://www.cronj.com/blog/browser-push-notifications-using-javascript/ . It also mentions how to handle when you don't wish to move your main site to HTTPs. (Node.js and JavaScript). – Akash Budhia Sep 04 '16 at 04:06
  • 2
    Here is complete guide and source code of mine. https://lahiiru.github.io/browser-push – TRiNE Dec 02 '16 at 12:57
  • 5
    Onesignal is free, but note how much data it captures from your users. Please read the ToS before using: https://onesignal.com/tos – Lemmings19 Dec 02 '17 at 01:26
  • 2
    LetsEncrypt.org means you should have no trouble getting HTTPS for everythign – That Realty Programmer Guy Apr 15 '18 at 16:57
  • 1
    Are you sure that [gorush](https://github.com/appleboy/gorush) from the Go Lang link is applicable here? Because I think it's a service for sending push notifications to iOS and Android. There are some Go libraries for the Web Push Protocol like [webpush-go](https://github.com/SherClockHolmes/webpush-go) and [web-push-go](https://github.com/gauntface/web-push-go). – Vladimir Vlasov Oct 12 '18 at 15:30
  • 1
    Also check this [Firefox document](https://support.mozilla.org/en-US/kb/push-notifications-firefox?as=u&utm_source=inproduct) about the subject – Accountant م Oct 31 '18 at 05:48
  • 1
    @VladimirVlasov Updated the answer. Thanks for pointing it out. – esafwan Dec 28 '18 at 18:08
  • @Accountantم Added it to the list. Thanks – esafwan Dec 28 '18 at 18:08
  • 1
    [PushAlert](https://pushalert.co) has also a free plan and they don't collect data. – koder May 04 '22 at 03:23
26

Javier covered Notifications and current limitations.

My suggestion: window.postMessage while we wait for the handicapped browser to catch up, else Worker.postMessage() to still be operating with Web Workers.

These can be the fallback option with dialog box message display handler, for when a Notification feature test fails or permission is denied.

Notification has-feature and denied-permission check:

if (!("Notification" in window) || (Notification.permission === "denied") ) {
    // use (window||Worker).postMessage() fallback ...
}
Remi Guan
  • 21,506
  • 17
  • 64
  • 87
greg.arnott
  • 1,622
  • 17
  • 16
14

You can push data from the server to the browser via Server Side Events. This is essentially a unidirectional stream that a client can "subscribe" to from a browser. From here, you could just create new Notification objects as SSEs stream into the browser:

var source = new EventSource('/events');

source.on('message', message => {
  var notification = new Notification(message.title, {
    body: message.body
  });
}); 

A bit old, but this article by Eric Bidelman explains the basics of SSE and provides some server code examples as well.

djfdev
  • 5,747
  • 3
  • 19
  • 38
14

this is simple way to do push notification for all browser https://pushjs.org

Push.create("Hello world!", {
body: "How's it hangin'?",
icon: '/icon.png',
timeout: 4000,
onClick: function () {
    window.focus();
    this.close();
 }
});
Nagarjun
  • 6,557
  • 5
  • 33
  • 51
11

GCM/APNS are only for Chrome and Safari respectively.

I think you may be looking for Notification:

https://developer.mozilla.org/en-US/docs/Web/API/notification

It works in Chrome, Firefox, Opera and Safari.

BananaNeil
  • 10,322
  • 7
  • 46
  • 66
Javier Conde
  • 2,553
  • 17
  • 25
11

I assume you are talking about real push notifications that can be delivered even when the user is not surfing your website (otherwise check out WebSockets or legacy methods like long polling).

Can we use GCM/APNS to send push notification to all Web Browsers including Firefox & Safari?

GCM is only for Chrome and APNs is only for Safari. Each browser manufacturer offers its own service.

If not via GCM can we have our own back-end to do the same?

The Push API requires two backends! One is offered by the browser manufacturer and is responsible for delivering the notification to the device. The other one should be yours (or you can use a third party service like Pushpad) and is responsible for triggering the notification and contacting the browser manufacturer's service (i.e. GCM, APNs, Mozilla push servers).

Disclosure: I am the Pushpad founder

collimarco
  • 34,231
  • 36
  • 108
  • 142
7

May I redefine you question as below

Can we have our own back-end to send push notification to Chrome, Firefox, Opera & Safari?

Yes. By today (2017/05), you can use same client and server side implementation to handle Chrome, Firefox and Opera (no Safari). Because they have implemented web push notifications in a same way. That is Push API protocol by W3C. But Safari have their own old architecture. So we have to maintain Safari separately.

Refer browser-push repo for guide lines to implement web push notification for your web-app with your own back-end. It explains with examples how you can add web push notification support for your web application without any third party services.

TRiNE
  • 5,020
  • 1
  • 29
  • 42
5

As of now GCM only works for chrome and android. similarly firefox and other browsers has their own api.

Now coming to the question how to implement push notification so that it will work for all common browsers with own back end.

  1. You need client side script code i.e service worker,refer( Google push notification). Though this remains same for other browsers.

2.after getting endpoint using Ajax save it along with browser name.

3.You need to create back end which has fields for title,message, icon,click URL as per your requirements. now after click on send notification, call a function say send_push(). In this write code for different browsers for example

3.1. for chrome

 $headers = array(
          'Authorization: key='.$api_key(your gcm key),
          'Content-Type: application/json',
     );
   $msg = array('to'=>'register id saved to your server');
   $url = 'https://android.googleapis.com/gcm/send';
   $ch = curl_init();

      // Set the url, number of POST vars, POST data
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
      curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($msg));

      $result = curl_exec($ch);

3.2. for mozilla

$headers = array(            
              'Content-Type: application/json',
              'TTL':6000
            );

       $url = 'https://updates.push.services.mozilla.com/wpush/v1/REGISTER_ID_TO SEND NOTIFICATION_ON';

      $ch = curl_init();

      // Set the url, number of POST vars, POST data
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);


      $result = curl_exec($ch);

for other browsers please google...

Draken
  • 3,134
  • 13
  • 34
  • 54
Arjun singh
  • 61
  • 1
  • 5
1

I suggest using pubnub. I tried using ServiceWorkers and PushNotification from the browser however, however when I tried it webviews did not support this.

https://www.pubnub.com/docs/web-javascript/pubnub-javascript-sdk

ColacX
  • 3,928
  • 6
  • 34
  • 36
0

Here you have a Full working html example.
Just replace image, text and here we go!

<html lang="en">
  <head>
    <meta charset="utf-8" />

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="script.js"></script>
    <link rel="icon" href="favicon.ico" type="image/png">
    <title>Push</title>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

  
  </head>

  <body>
    <div class="centrado">

    


<div class="card text-center shadow">
  <div class="card-header">
    Push Notifications 
  </div>
  <div class="card-body">
    <h5 class="card-title">Test for Push Notifications</h5>
    <p class="card-text">Click twice, first for the permission</p>
    <button class="btn btn-danger" id="btn-show-notification">Notify</button>
  </div>
  <div class="card-footer text-muted">
    aledc7
  </div>
</div>

</div>


  </body>



<script>
  $(document).ready(function () {
  $(document).on('DOMContentLoaded', function () {
    // Request desktop notifications permission on page load

    if (!Notification) {
      console.log('Notification is not compatible');
      return;
    }

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

  function showNotification() {
    if (Notification.permission !== 'granted') {
      Notification.requestPermission();
    } else {
      const options = {
        body: 'Your text for the Notification,
        dir: 'ltr',
        image: 'your_image.png' //must be 728x360px
      };
      const notification = new Notification('Title Notification', options);

      notification.onclick = function () {
        window.open('https://stackoverflow.com/users/10220740/ale-dc');
      };
    }
  }

  $('#btn-show-notification').on('click', showNotification);
});
</script>


<style>
  .centrado{
    /* Centrado Horizontal */
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    vertical-align: middle;

    /* Centrado Vertical */
    margin: 0;
    position: absolute;
    top: 50%;
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);


}

.shadow{
  filter: drop-shadow(2px 4px 8px #585858);
}


</style>

</html>
Ale DC
  • 1,646
  • 13
  • 20