Dynamic Web Notification using PHP and JavaScript Tutorial

In this tutorial, you will learn how to Implement a Dynamic Web Push Notification using PHP and JavaScript. The tutorial aims to provide IT/CS students a reference to learn the usage of JavaScript Notification API and Integrate it with PHP Language and Ajax requests. Here, snippets of a sample application will be provided. Also, I have provided the working source code zip file of the simple program that demonstrates the implementation of dynamic web push notifications.

What is JavaScript Notification API?

JavaScript comes with a Notification application program interface (API). It is an interface used for configuring display notifications to the end users' devices. The Notification methods are available in various web browsers. To know more about the browser compatibility of this API, visit JS Notification's Browser Compatibility.

How can we Implement Dynamic Web Push Notifications using PHP and JS?

As I mentioned above, Notification is a JavaScript API which means push notifications will be triggered using JavaScript. To integrate the said API to have dynamic notification content or information using PHP and MySQL Database, we can simply use HTTP Requests for fetching or retrieving the notification data.

Example

Here are the following snippets for a simple web application that demonstrate the implementation of Dynamic Web Push Notification using PHP and JavaScript.

MySQL Schema

For this demo application, we will be using the following MySQL Schema. Create a database named dummy_db and the table where the notification details will be stored at the notifications table.

  1.     CREATE TABLE `notifications` (
  2.         `id` bigint(30) NOT NULL AUTO_INCREMENT,
  3.         `title` text NOT NULL,
  4.         `url` text NOT NULL,
  5.         `image_url` text NOT NULL,
  6.         `description` text NOT NULL,
  7.         `status` varchar(20) NOT NULL DEFAULT 'unsent',
  8.         `created_at` datetime NOT NULL DEFAULT current_timestamp(),
  9.         `updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
  10.         PRIMARY KEY (`id`)

Database Connection

The following snippet is a PHP script named db-connect.php. It is a PHP file that contains the scripts for handling the connection between the application and the database.

  1. <?php
  2.  
  3. // Server Host
  4. $host = "localhost";
  5. // Server DB Username
  6. $uname = "root";
  7. // Server DB Password
  8. $password = "";
  9. // Server DB Name
  10. $dbname = "dummy_db";
  11.  
  12. $conn = new mysqli($host, $uname, $password, $dbname);
  13. if(!$conn){
  14.     die("Database Connection Failed.");
  15. }

Interface

The following snippet is an HTML file known as index.html. It contains the HTML script or the page interface elements for displaying the form for saving the notification details into the database.

  1. <!DOCTYPE html>
  2. <html lang="en">
  3.     <meta charset="UTF-8">
  4.     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Web Notification with PHP and JavaScript</title>
  7.     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
  8.     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  9.  
  10.     <script src="https://code.jquery.com/jquery-3.6.2.min.js" integrity="sha256-2krYZKh//PcchRtd+H+VyyQoZ/e3EcrkxhM8ycwASPA=" crossorigin="anonymous"></script>
  11.     <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/js/all.min.js" integrity="sha512-naukR7I+Nk6gp7p5TMA4ycgfxaZBJ7MO5iC3Fp6ySQyKFHOGfpkSZkYVWV5R7u7cfAicxanwYQ5D1e17EfJcMA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  12.     <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
  13.  
  14.     <style>
  15.         html, body{
  16.             height: 100%;
  17.             width: 100%;
  18.         }
  19.         body{
  20.             display: flex;
  21.             height: 100%;
  22.             width: 100%;
  23.             flex-direction: column;
  24.         }
  25.         body>nav, body>footer{
  26.             flex-shrink: 1;
  27.         }
  28.         body>main{
  29.             flex-shrink: 1;
  30.             flex-grow: 1;
  31.             overflow: auto;
  32.             margin: 1em 0;
  33.         }
  34.         pre{
  35.             min-height:20vh
  36.         }
  37.     </style>
  38. </head>
  39. <body style="background:#eff3fc">
  40.     <nav class="navbar navbar-expand-lg navbar-dark" style="background:#495C83">
  41.         <div class="container">
  42.             <a class="navbar-brand" href="./">Web Notification with PHP and JavaScript</a>
  43.             <div>
  44.                 <a href="https://sourcecodester.com" class="text-light fw-bolder h6 text-decoration-none" target="_blank">SourceCodester</a>
  45.             </div>
  46.         </div>
  47.     </nav>
  48.  
  49.     <main class="container-fluid">
  50.         <div class="col-lg-6 col-md-8 col-sm-12 col-xs-12 mx-auto">
  51.             <h2 class="text-center">Dynamic Web Notification using PHP and JavaScript</h2>
  52.             <hr>
  53.  
  54.             <div class="card mt-3 rounded-0">
  55.                 <div class="card-header">
  56.                     <div class="card-title"><b>Notification Form</b></div>
  57.                 </div>
  58.                 <div class="card-body rounded-0">
  59.                     <div class="container-fluid">
  60.                         <form action="" id="notif-form">
  61.                             <div class="mb-3">
  62.                                 <label for="title" class="form-label">Title</label>
  63.                                 <input type="text" class="form-control rounded-0" id="title" name="title" required="required">
  64.                             </div>
  65.                             <div class="mb-3">
  66.                                 <label for="url" class="form-label">URL</label>
  67.                                 <input type="url" class="form-control rounded-0" id="url" name="url" required="required">
  68.                             </div>
  69.                             <div class="mb-3">
  70.                                 <label for="image_url" class="form-label">Banner URL</label>
  71.                                 <input type="url" class="form-control rounded-0" id="image_url" name="image_url">
  72.                             </div>
  73.                             <div class="mb-3">
  74.                                 <label for="description" class="form-label">Description</label>
  75.                                 <textarea rows="3" class="form-control rounded-0" id="description" name="description" required="required"></textarea>
  76.                             </div>
  77.                         </form>
  78.                     </div>
  79.                 </div>
  80.                 <div class="card-footer py-2">
  81.                     <div class="row justify-content-center">
  82.                         <div class="col-lg-4 col-md-6 col-sm-10 col-xs-12">
  83.                             <button class="btn btn-block w-100 btn-primary rounded-pill" form="notif-form"><i class="fa fa-save"></i> Save Notification</button>
  84.                         </div>
  85.                         <div class="col-lg-4 col-md-6 col-sm-10 col-xs-12">
  86.                             <button class="btn btn-block w-100 btn-default border rounded-pill" type="reset" form="notif-form"><i class="fa fa-times"></i> Cancel</button>
  87.                         </div>
  88.                     </div>
  89.                 </div>
  90.             </div>
  91.         </div>
  92.     </main>
  93. <footer class="container-fluid py-3" style="background:#495C83; color:#fff">
  94.     <div class="container-fluid my-2">
  95.         <div class="text-center">
  96.             <b>Web Notification with PHP and JavaScript &copy; 2022</b>
  97.         </div>
  98.     </div>
  99. </footer>
  100. </body>
  101. <script src="script.js"></script>
  102. </html>

PHP API

Save Notification

The following snippet is a PHP script named save_notification.php. The snippet saves the notification details into the database. By default, the notification details status is set as "unsent".

  1. <?php
  2. require_once("db-connect.php");
  3.  
  4. $title = addslashes($conn->real_escape_string($_POST['title']));
  5. $description = addslashes($conn->real_escape_string($_POST['description']));
  6. $url = addslashes($conn->real_escape_string($_POST['url']));
  7. $image_url = addslashes($conn->real_escape_string($_POST['image_url']));
  8.  
  9. $insert_sql = "INSERT INTO `notifications` (`title`, `url`, `image_url`, `description`) VALUES ('{$title}', '{$url}', '{$image_url}', '$description')";
  10.  
  11. $insert = $conn->query($insert_sql);
  12. if($insert){
  13.     $response['status'] = 'success';
  14.     $response['msg'] = 'Notification has been added successfully.';
  15. }else{
  16.     $response['status'] = 'error';
  17.     $response['msg'] = 'Notification has failed to save. Error: ' . $conn->error;
  18. }
  19.  
  20. echo json_encode($response);
  21. ?>

Retrieve Pending Notifications

The following script is a PHP file named get_notifications.php. The script retrieves the pending notification details that will be used for creating the Dynamic Push Notification.

  1. <?php
  2. require_once('db-connect.php');
  3.  
  4. $notif_sql = "SELECT * FROM `notifications` where `status` = 'unsent'";
  5. $notif_qry = $conn->query($notif_sql);
  6.  
  7. $notifs = [];
  8. if($notif_qry->num_rows > 0){
  9.    
  10.     $notifs = $notif_qry->fetch_all(MYSQLI_ASSOC);
  11. }
  12.  
  13. echo json_encode($notifs);

Update Notifications

The following snippet is a PHP file named update_notification.php. It is a PHP script that updates the notification details as sent after the web push notification is created.

  1. <?php
  2. require_once("db-connect.php");
  3.  
  4. $update_sql = "UPDATE `notifications` set `status` = 'sent' where `id` = '{$_POST['id']}' ";
  5. $update = $conn->query($update_sql);
  6. if($update){
  7.     $response['status'] = 'success';
  8. }else{
  9.     $response['error'] = "An error occurred. Erro: ".$conn->error;
  10. }
  11. echo json_encode($response);

JavaScript

Lastly, the following snippet is a JavaScript file known as script.js. It is contains the scripts for submitting the notification form details, retrieving the pending notfications, creating Notification, and display notification to the users' devices.

  1. /**
  2. * Get Pending Notifications
  3. */
  4. const send_notif = () =>{
  5.  
  6.     if("Notification" in window){
  7.         if(Notification.permission === 'granted'){
  8.             $.ajax({
  9.                 url:"get_notifications.php",
  10.                 dataType:'json',
  11.                 error: err => {
  12.                     console.error(err)
  13.                 },
  14.                 success:function(data){
  15.                     Object.values(data).forEach(notif => {
  16.                        
  17.                                 var notif_data = {}
  18.                                 notif_data.icon = "http://localhost/web_notification/test-icon.png";
  19.                                 notif_data.body = notif.description;
  20.                                 notif_data.image = notif.image_url;
  21.                                 var webNotification = WebPushNotification(notif.title, notif.url, notif_data)
  22.                                 // console.log(webNotification)
  23.                                 if(webNotification !== undefined){
  24.                                     /**
  25.                                     * Update Notification
  26.                                     */
  27.                                     update_notification(notif.id)
  28.                                 }
  29.                        
  30.                     })
  31.                 },
  32.                 complete: ()=>{
  33.  
  34.                     setTimeout(()=>{
  35.                         send_notif();
  36.                     }, 3000)
  37.                    
  38.                 }
  39.             })
  40.         }
  41.     }
  42.    
  43. }
  44.  
  45. /**
  46. * Update Notification to sent
  47. * @param {int(notfication ID)} $id
  48. * @returns
  49. */
  50.  
  51. const update_notification = ($id) =>{
  52.     return $.ajax({
  53.         url:"update_notification.php",
  54.         method:'POST',
  55.         data:{id:$id},
  56.         dataType:'json',
  57.         error:err=>{
  58.             console.error(err)
  59.         },
  60.         success:function(response){
  61.             if(!!response.status){
  62.                 if(response.status == 'success'){
  63.                     console.log(`Notification [${$id}] has been updated to sent.`)
  64.                 }else{
  65.                     console.error(response)
  66.                 }
  67.             }else if(!!response.error){
  68.                 console.error(response.error)
  69.             }else{
  70.                 console.error(response)
  71.             }
  72.         }
  73.     })
  74. }
  75. $(document).ready(function(){
  76.    
  77.    
  78.     wpn_ask_permission();
  79.     send_notif();
  80.  
  81.     /**
  82.     * Form Submission
  83.     */
  84.  
  85.     $('#notif-form').submit(function(e){
  86.         e.preventDefault();
  87.         var _this = $(this)
  88.         _this.find('button').attr('disabled', true)
  89.         var msg = $("<div>")
  90.         msg.hide()
  91.         msg.addClass("alert form-msg")
  92.         $('.form-msg').remove()
  93.         $.ajax({
  94.             url:"save_notification.php",
  95.             method:'POST',
  96.             data:_this.serialize(),
  97.             dataType:"json",
  98.             error: err =>{
  99.                 alert("An error occurred while saving the notifcation data.");
  100.                 console.error(err)
  101.                 _this.find('button').attr('disabled', true)
  102.             },
  103.             success:function(response){
  104.                 if(!!response.status){
  105.                     if(response.status == 'success'){
  106.                         msg.text(response.msg)
  107.                         msg.addClass('alert-success')
  108.                         _this.prepend(msg)
  109.                         msg.show('toggle')
  110.                     }else{
  111.                         msg.text(response.msg)
  112.                         msg.addClass('alert-danger')
  113.                         _this.prepend(msg)
  114.                         msg.show('toggle')
  115.                     }
  116.                 }else{
  117.                     alert("An error occurred while saving the notifcation data.");
  118.                     console.error(response)
  119.                 }
  120.                 _this[0].reset()
  121.                 _this.find('button').attr('disabled', true)
  122.  
  123.             }
  124.         })
  125.     })
  126. })
  127.  
  128. window.wpn_ask_permission = function (){
  129.     if(!("Notification" in window)){
  130.         alert("Your browser does not support Desktop Notification.");
  131.         console.error("Your browser does not support Desktop Notification.");
  132.     }else{
  133.         console.log(Notification.permission)
  134.         if(Notification.permission !== 'granted' && Notification.permission !== 'denied'){
  135.             Notification.requestPermission().then( permission =>{
  136.                 if(permission ==='granted'){
  137.                     alert("Notification Permission is granted");
  138.                 }else if(permission ==='denied'){
  139.                     alert("Notification Permission is not granted");
  140.                 }
  141.                 location.reload();
  142.             } )
  143.         }
  144.     }
  145. }
  146.  
  147. window.WebPushNotification = function (title="", $action="", data = {}){
  148.     var notification ;
  149.     if(("Notification" in window)){
  150.         if(Notification.permission === 'default'){
  151.             wpn_ask_permission()
  152.         }else if(Notification.permission === 'granted'){
  153.             notification = new Notification(title,data)
  154.  
  155.             notification.onclick = (event) => {
  156.                 window.open($action)
  157.             }
  158.         }
  159.     }
  160.  
  161.     return notification;
  162. }

Kindly replace the Notification Icon in the script with your preferred and downloaded notification logo or icon.

There you go! You can now test the application on your end and see if it works properly. I also provided the complete source code zip file on this article and is free to download. The download button is located below this article.

Snapshot

Here are the images of the result of the demo application.

Page Interface

Dynamic Web Push Notification Demo App using PHP and JS

Notification

Dynamic Web Push Notification Demo App using PHP and JS

DEMO Video

That's it! I hope this Dynamic Web Push Notification using PHP and JavaScript Tutorial helps you with what you are looking for and you'll find it useful for your current and future projects.

Explore more on this website for more Tutorials and Free Source Codes.

Happy Coding :)

Comments

Add new comment