title: How to implement service worker?
body: <p>I have already been through different blogs explaning about service worker , one of them is  <a href="https://developers.google.com/web/updates/2015/03/push-notificatons-on-the-open-web" rel="nofollow">open Web Push notification</a>. I followed the instructions in Open Web Push notification and implemented a code which creates a curl registration id.Once the registration id is created i put it in database.but i get no notification . i normally enabled gcm in google console .
  Should I also write gcm server and client code, as I have read a lot of blogs ,none said to do so. 
  what should i do to get notifications.</p>
  
  <p>please refer below the codes if i have missed anything.</p>
  
  <p><strong><code>index.html</code></strong></p>
  
  <pre><code>&lt;!doctype html&gt;
  
  &lt;html lang="en"&gt;
  &lt;head&gt;
  
      &lt;title&gt;Push Messaging &amp;amp; Notifications&lt;/title&gt;
  
      &lt;!-- Add to homescreen for Chrome on Android --&gt;
      &lt;meta name="mobile-web-app-capable" content="yes"&gt;
      &lt;link rel="icon" sizes="192x192" href="../images/touch/chrome-touch-icon-192x192.png"&gt;
  
      &lt;!-- Add to homescreen for Safari on iOS --&gt;
      &lt;meta name="apple-mobile-web-app-title" content="Push Messaging and Notifications Sample"&gt;
  
      &lt;meta name="apple-mobile-web-app-capable" content="yes"&gt;
      &lt;meta name="apple-mobile-web-app-status-bar-style" content="black"&gt;
      &lt;link rel="apple-touch-icon-precomposed" href="../images/apple-touch-icon-precomposed.png"&gt;
  
      &lt;!-- Tile icon for Win8 (144x144 + tile color) --&gt;
      &lt;meta name="msapplication-TileImage" content="images/touch/ms-touch-icon-144x144-precomposed.png"&gt;
      &lt;meta name="msapplication-TileColor" content="#3372DF"&gt;
  
      &lt;link rel="icon" href="../images/favicon.ico"&gt;
  
      &lt;!-- Include manifest file in the page --&gt;
      &lt;link rel="manifest" href="manifest.json"&gt;
  
  
  &lt;body&gt;
      &lt;h1&gt;Push Messaging &amp;amp; Notifications&lt;/h1&gt;
  
      &lt;p&gt;
          &lt;button class="js-push-button" disabled&gt;
              Enable Push Messages
          &lt;/button&gt;
      &lt;/p&gt;
  
      &lt;br /&gt;
      &lt;br /&gt;
  
      &lt;h2&gt;cURL Command to Send Push&lt;/h2&gt;
      &lt;div class="js-curl-command"&gt;&lt;/div&gt;
  
      &lt;script src="config.js"&gt;&lt;/script&gt;
      &lt;script src="demo.js"&gt;&lt;/script&gt;
      &lt;script src="main.js"&gt;&lt;/script&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p><strong>main.js</strong></p>
  
  <pre><code>    'use strict';
  
  var API_KEY = window.GoogleSamples.Config.gcmAPIKey;
  var GCM_ENDPOINT = 'https://android.googleapis.com/gcm/send';
  
  var curlCommandDiv = document.querySelector('.js-curl-command');
  var isPushEnabled = false;
  
  // This method handles the removal of subscriptionId
  // in Chrome 44 by concatenating the subscription Id
  // to the subscription endpoint
  function endpointWorkaround(pushSubscription) {
      // Make sure we only mess with GCM
      if (pushSubscription.endpoint.indexOf('https://android.googleapis.com/gcm/send') !== 0) {
          return pushSubscription.endpoint;
      }
  
      var mergedEndpoint = pushSubscription.endpoint;
      // Chrome 42 + 43 will not have the subscriptionId attached
      // to the endpoint.
      if (pushSubscription.subscriptionId &amp;&amp;
        pushSubscription.endpoint.indexOf(pushSubscription.subscriptionId) === -1) {
          // Handle version 42 where you have separate subId and Endpoint
          mergedEndpoint = pushSubscription.endpoint + '/' +
            pushSubscription.subscriptionId;
  
      }
      return mergedEndpoint;
  }
  
  function sendSubscriptionToServer(subscription) {
      // TODO: Send the subscription.endpoint
      // to your server and save it to send a
      // push message at a later date
      //
      // For compatibly of Chrome 43, get the endpoint via
      // endpointWorkaround(subscription)
      var sub = subscription.endpoint;
      var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (xhttp.readyState == 4 &amp;&amp; xhttp.status == 200) {
        //document.getElementById("demo").innerHTML = xhttp.responseText;
      }
    }
    xhttp.open("POST", "myusers.php?id="+sub, true);
    xhttp.send();
  
      console.log(subscription.endpoint);
  
      var mergedEndpoint = endpointWorkaround(subscription);
  
      // This is just for demo purposes / an easy to test by
      // generating the appropriate cURL command
      showCurlCommand(mergedEndpoint);
  }
  
  // NOTE: This code is only suitable for GCM endpoints,
  // When another browser has a working version, alter
  // this to send a PUSH request directly to the endpoint
  function showCurlCommand(mergedEndpoint) {
      // The curl command to trigger a push message straight from GCM
      if (mergedEndpoint.indexOf(GCM_ENDPOINT) !== 0) {
          window.Demo.debug.log('This browser isn\'t currently ' +
            'supported for this demo');
          return;
      }
  
      var endpointSections = mergedEndpoint.split('/');
      var subscriptionId = endpointSections[endpointSections.length - 1];
  
      var curlCommand = 'curl --header "Authorization: key=' + API_KEY +
        '" --header Content-Type:"application/json" ' + GCM_ENDPOINT +
        ' -d "{\\"registration_ids\\":[\\"' + subscriptionId + '\\"]}"';
  
      curlCommandDiv.textContent = curlCommand;
  }
  
  function unsubscribe() {
      var pushButton = document.querySelector('.js-push-button');
      pushButton.disabled = true;
      curlCommandDiv.textContent = '';
  
      navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) {
          // To unsubscribe from push messaging, you need get the
          // subcription object, which you can call unsubscribe() on.
          serviceWorkerRegistration.pushManager.getSubscription().then(
            function (pushSubscription) {
                // Check we have a subscription to unsubscribe
                if (!pushSubscription) {
                    // No subscription object, so set the state
                    // to allow the user to subscribe to push
                    isPushEnabled = false;
                    pushButton.disabled = false;
                    pushButton.textContent = 'Enable Push Messages';
                    return;
                }
  
                // TODO: Make a request to your server to remove
                // the users data from your data store so you
                // don't attempt to send them push messages anymore
  
                // We have a subcription, so call unsubscribe on it
                pushSubscription.unsubscribe().then(function (successful) {
                    pushButton.disabled = false;
                    pushButton.textContent = 'Enable Push Messages';
                    isPushEnabled = false;
                }).catch(function (e) {
                    // We failed to unsubscribe, this can lead to
                    // an unusual state, so may be best to remove
                    // the subscription id from your data store and
                    // inform the user that you disabled push
  
                    window.Demo.debug.log('Unsubscription error: ', e);
                    pushButton.disabled = false;
                });
            }).catch(function (e) {
                window.Demo.debug.log('Error thrown while unsubscribing from ' +
                  'push messaging.', e);
            });
      });
  }
  
  function subscribe() {
      // Disable the button so it can't be changed while
      // we process the permission request
      var pushButton = document.querySelector('.js-push-button');
      pushButton.disabled = true;
  
      navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) {
          serviceWorkerRegistration.pushManager.subscribe({ userVisibleOnly: true })
            .then(function (subscription) {
                // The subscription was successful
                isPushEnabled = true;
                pushButton.textContent = 'Disable Push Messages';
                pushButton.disabled = false;
  
                // TODO: Send the subscription subscription.endpoint
                // to your server and save it to send a push message
                // at a later date
                return sendSubscriptionToServer(subscription);
            })
            .catch(function (e) {
                if (Notification.permission === 'denied') {
                    // The user denied the notification permission which
                    // means we failed to subscribe and the user will need
                    // to manually change the notification permission to
                    // subscribe to push messages
                    window.Demo.debug.log('Permission for Notifications was denied');
                    pushButton.disabled = true;
                } else {
                    // A problem occurred with the subscription, this can
                    // often be down to an issue or lack of the gcm_sender_id
                    // and / or gcm_user_visible_only
                    window.Demo.debug.log('Unable to subscribe to push.', e);
                    pushButton.disabled = false;
                    pushButton.textContent = 'Enable Push Messages';
                }
            });
      });
  }
  
  // Once the service worker is registered set the initial state
  function initialiseState() {
      // Are Notifications supported in the service worker?
      if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
          window.Demo.debug.log('Notifications aren\'t supported.');
          return;
      }
  
      // Check the current Notification permission.
      // If its denied, it's a permanent block until the
      // user changes the permission
      if (Notification.permission === 'denied') {
          window.Demo.debug.log('The user has blocked notifications.');
          return;
      }
  
      // Check if push messaging is supported
      if (!('PushManager' in window)) {
          window.Demo.debug.log('Push messaging isn\'t supported.');
          return;
      }
  
      // We need the service worker registration to check for a subscription
      navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) {
          // Do we already have a push message subscription?
          serviceWorkerRegistration.pushManager.getSubscription()
            .then(function (subscription) {
                // Enable any UI which subscribes / unsubscribes from
                // push messages.
                var pushButton = document.querySelector('.js-push-button');
                pushButton.disabled = false;
  
                if (!subscription) {
                    // We aren’t subscribed to push, so set UI
                    // to allow the user to enable push
                    return;
                }
  
                // Keep your server in sync with the latest subscription
                sendSubscriptionToServer(subscription);
  
                // Set your UI to show they have subscribed for
                // push messages
                pushButton.textContent = 'Disable Push Messages';
                isPushEnabled = true;
            })
            .catch(function (err) {
                window.Demo.debug.log('Error during getSubscription()', err);
            });
      });
  }
  
  window.addEventListener('load', function () {
      var pushButton = document.querySelector('.js-push-button');
      pushButton.addEventListener('click', function () {
          if (isPushEnabled) {
              unsubscribe();
          } else {
              subscribe();
          }
      });
  
      // Check that service workers are supported, if so, progressively
      // enhance and add push messaging support, otherwise continue without it.
      if ('serviceWorker' in navigator) {
          navigator.serviceWorker.register('service-worker.js')
          .then(initialiseState);
      } else {
          window.Demo.debug.log('Service workers aren\'t supported in this browser.');
      }
  });
  </code></pre>
  
  <p><strong>config.js</strong></p>
  
  <pre><code>window.GoogleSamples = window.GoogleSamples || {};
  window.GoogleSamples.Config = window.GoogleSamples.Config || {
      gcmAPIKey: '&amp;lt;Your Public API Key ...&amp;gt;'
  };
  </code></pre>
  
  <p><strong>service-worker.js</strong></p>
  
  <pre><code>'use strict';
  
  self.addEventListener('push', function (event) {
      console.log('Received a push message', event);
  
      var title = 'Yay a message.';
      var body = 'We have received a push message.';
      var icon = '/images/icon-192x192.png';
      var tag = 'simple-push-demo-notification-tag';
  
      event.waitUntil(
  
        self.registration.showNotification(title, {
            body: body,
            icon: icon,
            tag: tag
        })
      );
  });
  
  
  self.addEventListener('notificationclick', function (event) {
      console.log('On notification click: ', event.notification.tag);
      // Android doesn’t close the notification when you click on it
      // See: http://crbug.com/463146
      event.notification.close();
  
      // This looks to see if the current is already open and
      // focuses if it is
      event.waitUntil(clients.matchAll({
          type: "window"
      }).then(function (clientList) {
          for (var i = 0; i &lt; clientList.length; i++) {
              var client = clientList[i];
              if (client.url == '/' &amp;&amp; 'focus' in client)
                  return client.focus();
          }
          if (clients.openWindow)
              return clients.openWindow('/');
      }));
  
  });
  </code></pre>
  
  <p><strong>demo.js</strong></p>
  
  <pre><code> 'use strict';
  
      function Debug() {
  
      }
  
      Debug.prototype.log = function () {
          var paragraphElement = document.createElement('p');
          paragraphElement.textContent = Array.prototype.join.call(arguments, '');
          document.querySelector('.js-log').appendChild(paragraphElement);
      }
  
      window.addEventListener('load', function () {
          var logDiv = document.createElement('div');
          logDiv.classList.add('js-log');
  
          var heading = document.createElement('h2');
          heading.textContent = 'Log';
          logDiv.appendChild(heading);
  
          document.body.appendChild(logDiv);
  
          window.Demo = window.Demo || {};
          window.Demo.debug = window.Demo.debug || new Debug();
      });
  </code></pre>
  
  <p>after writing all this code what else can be done ??
  I have not worked with gcm so finding hard time enabling,need help.</p>