Here is the method to Create Web Push Notification service by Using Google Firebase Cloud Messaging and Firebase real-time database.

Free Web Push Notification Service for Bloggers

Requirements

  • Firebase Project
  • HTTPS Enabled Blog/website

Supported & Tested Platforms

  • Wordpress
  • Ghost SMS
  • Static & Dynamic Sites
  • its Not Supported on Blogspot Blogging Platform (Try OneSingal for blogger blogs)

Firebase Web Push Notification

Example Setup (Test this on Static site)

  • index.html
  • notification.js
  • firebase-messaging-sw.js
  • manifest.json

Before testing this Create a New Project on Firebase

index.html


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Push Notification</title>


<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

<link rel="manifest" href="/manifest.json">

</head>
<body>
<br />

<center><h2>Hello World</h2></center>

<!-- Web Push Notification -->
<script src="https://www.gstatic.com/firebasejs/3.7.4/firebase.js"></script>
<script src="notification.js"></script>

</body>
</html>

manifest.json

{
  "//": "Some browsers will use this to enable push notifications.",
  "//": "It is the same for all projects, this is not your project's sender ID",
  "gcm_sender_id": "103953800507"
}

Firebase Web SDK Setup - Set up

Firebase 4x web SDK Versions are not working well so I use 3.7.4 SDK Version

notification.js


// Initialize Firebase - https://firebase.google.com/docs/web/setup
  var config = {
    apiKey: "YOUR FIREBASE PROJECT API KEY",
    authDomain: "YOUR FIREBASE PROJECT AUTH DOMAIN",
    databaseURL: "YOUR FIREBASE PROJECT DATABASE URL",
    projectId: "YOUR FIREBASE PORJECT ID",
    storageBucket: "YOUR FIREBASE STORAGE BUCKET URL",
    messagingSenderId: "YOUR FIREBASE PROJECT SENDER ID"
  };
  firebase.initializeApp(config);

const messaging = firebase.messaging();

messaging.requestPermission()
    .then(function() {
        return messaging.getToken();
    })
    .then(function(token) {
        // send rest call to add to database
        $.ajax('https://example.firebaseio.com/pushtokens/'+token+'.json', {
            method: 'PUT',
            data: 'true',
            error: function(err) {
            }
        });
    })
    .catch(function(err) {
        console.log('Permission denied');
    });

  • Replace the https://example.firebaseio.com/ with your Firebase realtime Database URL (you can get your DB URL on DATA Section in Realtime Database)
  • Don't remove +token+'.json'

Update DB Rules

  • Next Update the default database rules for store the FCM Tokens
  • Open your Firebase Project
  • Goto Database > Realtime Database > Rules
  • Replace the Default DB URL with this Below DB Rule
 {
  "rules": {
    ".read": "auth != null",
    ".write": "auth != true"
  }
}
  • Click Publish to Update the Rule

firebase-messaging-sw.js

  • Put firebase-messaging-sw.js (Firebase Service Worker) in Main root Directory don't put this File on static or assets folder

https://example.com/firebase-messaging-sw.js


importScripts("https://www.gstatic.com/firebasejs/3.7.4/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/3.7.4/firebase-messaging.js");

firebase.initializeApp({
    'messagingSenderId': 'YOUR FIREBASE PROJECT SENDER ID'
  });

  const messaging = firebase.messaging();

  • All the FCM Tokens are Store in the Firebase Real-time Database
  • Use the Stored FCM token to Send Web Push Notification

Send Push Notification

Send Firebase Web Push Notification via PHP cURL

push.php


<?php

// Server key from Firebase Console
define( 'API_ACCESS_KEY', 'YOUR FIREBASE CLOUD MESSAGING API KEY' ); // Replace YOUR FIREBASE CLOUD MESSAGING API KEY with your Firebase Cloud Messaging server Key

if($_SERVER["REQUEST_METHOD"] == "POST")
{

// POST values
$token= $_POST["token"];
$title= $_POST["title"];
$message= $_POST["message"];
$postlink= $_POST["postlink"];

$token = htmlspecialchars($token,ENT_COMPAT);
$title = htmlspecialchars($title,ENT_COMPAT);
$message = htmlspecialchars($message,ENT_COMPAT);
$postlink = htmlspecialchars($postlink,ENT_COMPAT);

// Push Data's
$data = array(
"to" => "$token",
"notification" => array( 
"title" => "$title", 
"body" => "$message", 
"icon" => "https://example.com/icon.png", // Replace https://example.com/icon.png with your PUSH ICON URL
"click_action" => "$postlink")
);

// Print Output in JSON Format
$data_string = json_encode($data); 
     
// FCM API Token URL
$url = "https://fcm.googleapis.com/fcm/send";

//Curl Headers
$headers = array
(
     'Authorization: key=' . API_ACCESS_KEY, 
     'Content-Type: application/json'
);  

$ch = curl_init();  
curl_setopt($ch, CURLOPT_URL, $url);                                                                 
curl_setopt($ch, CURLOPT_POST, 1);  
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_POSTFIELDS, $data_string);                                                                  
                                                                                                                     
// Variable for Print the Result
$result = curl_exec($ch);

curl_close ($ch);

}

?>

<!DOCTYPE html>
<html lang="en">
<head>

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<title>FCM Push Notification</title>
<meta name="Description" content="Subscribe to our Blog Post Updates.">

<!-- CSS and Fonts -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.9/css/all.css" integrity="sha384-5SOiIsAziJl6AWe0HWRKTXlfcSHKmYV4RBF18PPJ173Kzn7jzMyFuTtk8JA7QQG1" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Exo+2" rel="stylesheet">

<style>
body {
  background: #eee !important;
  font-family: 'Exo 2', sans-serif;
}
.login-form{
  margin:3% auto 0;
  max-width:380px;
}
.login-form h1{
  font-size: 30pt;
  font-weight: 700;
    letter-spacing: -1px;
    font-family: 'Exo 2', sans-serif;
}
.form-header,.form-footer{
  background-color: rgba(255, 255, 255, .8);
    border: 1px solid rgba(0,0,0,0.1);
}
.form-signin{
  padding: 45px 35px 45px;
    background-color: #fff;
    border: 1px solid rgba(0,0,0,0.1);  
    border-bottom: 0px; 
    border-top: 0px;  
}
.form-register{
  padding: 45px 35px 45px;
    background-color: #fff;
    border: 1px solid rgba(0,0,0,0.1);  
    border-bottom: 0px; 
    border-top: 0px; 
}
.form-header{
  text-align: center;
  padding: 15px 40px;
  border-radius: 10px 10px 0 0;
}
.form-header i{font-size:60px;}
.form-footer {
  padding: 15px 40px; 
}
.form-signin-heading{
  margin-bottom: 30px;
}
.bt-login{
    background-color: #ff8627;
    color: #ffffff;
    padding-bottom: 10px;
    padding-top: 10px;
    transition: background-color 300ms linear 0s;
}
.form-signin .form-control, .form-register .form-control{
  position: relative;
  height: auto;
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
  padding: 10px;
  font-size: 16px;
}
.form-signin .form-control:focus, .form-register .form-control:focus {
  z-index: 2;
}
.form-signin input[type="email"] {
  margin-bottom: -1px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}
input.parsley-error,
select.parsley-error,
textarea.parsley-error {    
    border-color:#843534;
    box-shadow: none;
}
input.parsley-error:focus,
select.parsley-error:focus,
textarea.parsley-error:focus {    
    border-color:#843534;
    box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483
}
.parsley-errors-list {
    list-style-type: none;
    opacity: 0;
    transition: all .3s ease-in;

    color: #d16e6c;
    margin-top: 5px;
    margin-bottom: 0;
  padding-left: 0;
}
.parsley-errors-list.filled {
    opacity: 1;
    color: #a94442;
}
pre {
  background-color: #f7f7f9;
  border: 1px solid #e1e1e8;
color: #336cac;
font-size: 17px;
}
pre:before {
    color: #333;
}
.btn {
    margin-bottom:4px;white-space: normal;
}
.input {
    margin-bottom:4px;white-space: normal;
}
</style>


<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->


<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

</head>
<body>
<br />

<div class="container">
<div class="login-form">
<h2 class="text-center">Send Push Notification</h2>
<br>
<div class="form-header">
<i class="fas fa-bell"></i>
</div>
<form class="form-signin" method="post">
<div class="form-group">
<textarea class="form-control" name="token" placeholder="FCM Token" data-parsley-required="true" data-parsley-error-message="Please Enter the Token"></textarea>
</div>
<div class="form-group">
<input class="form-control" type="text" name="title" placeholder="Push Title" data-parsley-required="true" data-parsley-error-message="Enter the Title">
</div>
<div class="form-group">
<textarea class="form-control" name="message" placeholder="Push Message" data-parsley-required="true" data-parsley-error-message="Enter a Push Message"></textarea>
</div>
<div class="form-group">
<input class="form-control" type="text" name="postlink" placeholder="Click Action Link" data-parsley-required="true" data-parsley-error-message="Enter a Link">
</div>
<button type="submit" class="btn btn-block bt-login">Send Push</button>
</form>
<br />
<br />
</div>
</div>

<div class="container">
<div class="row">
<div class="col-lg-6 col-lg-offset-3 mx-auto">
<?php
if(isset($_POST['token'])) {
// Display Output
echo "<p>&nbsp;</p>";
echo "<pre>$result</pre>";
echo "<pre>The Json Data : $data_string</pre>";
}
?>
</div>
</div>
</div>
<br />
<br />

<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/parsley.js/2.8.1/parsley.min.js" integrity="sha256-XqEmjxbIPXDk11mQpk9cpZxYT+8mRyVIkko8mQzX3y8=" crossorigin="anonymous"></script>

<script>
$(document).ready(function(){
  $('form').parsley();
});
</script>

</body>
</html>


Send Push Notification via cURL

curl -X POST -H "Authorization: key=YOUR FIREBASE CLOUD MESSAGING API KEY" -H "Content-Type: application/json" -d '{
  "notification": {
    "title": "Hello World",
    "body": "Test Push",
    "icon": "push.png",
    "click_action": "https://example.com"
  },
  "to": "FCM TOKEN"
}' "https://fcm.googleapis.com/fcm/send"

Find Active & Active Tokens

if you get 1 on success field then the token is active.if you get 0 on success field the token is inactive.
Remove the inactive tokens from the database

Active Token Output

{
	"multicast_id": XXXXXXXXXXXXXXXXXX,
	"success": 1,
	"failure": 0,
	"canonical_ids": 0,
	"results": [{
		"message_id": "0:XXXXXXXXXXXXXXXXXXXX"
	}]
}

inactive Token Output

{
	"multicast_id": XXXXXXXXXXXXXXXXXX,
	"success": 0,
	"failure": 1,
	"canonical_ids": 0,
	"results": [{
		"error": "NotRegistered"
	}]
}

From the Editor's Desk

If you Having any Doubts in setup Feel Free to Contact Me I will Guide to set up the Firebase Push Notification service for your website & blog