Git Product home page Git Product logo

push-notification's Introduction

WEB PUSH NOTIFICATION

Push notification là cơ chế gửi thông báo cho người dùng từ website vào một sự kiện cụ thể nhằm đưa người dùng trở lại website giúp tăng tương tác giữa người dùng với website.

Ưu điểm và nhược điểm của push notification

Ưu điểm:

  • Có thể gửi thông báo đến bất kỳ thiết bị nào hỗ trợ trình duyệt và trình duyệt đó hỗ trợ push notification.
  • Người dùng không cần phải cài đặt các phần mềm hỗ trợ nào.
  • Người dùng có thể nhận được thông báo ngay cả khi đang duyệt website khác.
  • Tăng tương tác giữa web và người dùng.

Nhược điểm:

Việc gửi push notification liên tục hoặc notify không có nội dung cụ thể, không đúng thời điểm có thể dẫn tới việc phản tác dụng của push notification. #Các phiên bản browser hỗ trợ

Phiên bản trên PC

Chrome Edge Safari Firefox Opera IE
v22+ v14+ v6+ với Mac OSX 10.6+ v22+ v25+ Không hỗ trợ
##Phiên bản trên mobile:
Chrome Android Safari iOS Samsung Internet Opera Min Opera Mobile UC Browser Android Android Browser Firefox for Android QQ Browser Baidu Browser KaiOS Browser Chrome IOS
v112 v16.4+ v4 với webkit Không hỗ trợ v73 với webkit v13.4 v4.4 với webkit v110 Không hỗ trợ Không hỗ trợ v2.5+ check thấy v112.0.5615.167 chưa hỗ trợ
  • Chrome Android yêu cầu bắt buộc phải tạo 1 service worker.
  • Firefox không hỗ trợ thông báo được gửi liền sát nhau.
  • Thông báo của firefox sẽ biến mất trong vãi giây.
  • IOS không hỗ trợ invisible push notifications (A silent push notification). Là những thông báo không có cảnh báo cho người dùng.

Các bước thực hiện

sequence

Khởi tạo

  • Đầu tiên, ta cần tạo một file trống sw.js được đặt cùng cấp thư mục với file index.html. Đây sẽ là service worker của bạn.
  • Tiếp theo, ta sẽ tạo file main.js, file này sẽ được load trong index.html.
<script src="scripts/main.js"></script>
  • Tạo một biến toàn cục pushButton trong file main.js được gán với thẻ button js-push-btn trong index.html
const pushButton = document.querySelector('.js-push-btn');
<button disabled class="js-push-btn mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect">
  Enable Push Messaging
</button>
  • Tạo một biến toàn cục swRegistration lưu thông tin của service worker gán là null vì ban đấu service worker chưa được khởi tạo
let swRegistration = null;
  • Tạo một biến toàn bộ isSubscribed để kiểm tra người dùng đã đăng ký nhận thông báo hay không
let isSubscribed = false;

Lấy public key từ server

Vì đây là một sản phẩm demo nên ta sẽ thực hiện lấy public key và gửi thông báo từ một server demo có sẵn. Truy cập https://web-push-codelab.glitch.me/. Ở đây ta có thể thấy Public KeyPrivate Key như hình bên dưới:

get public key

Tạo một biến toàn cục applicationServerPublicKey và gán bằng giá trị Public Key mà ta vừa lấy được

const applicationServerPublicKey = "Your public key";
{
  "name": "test",
  "short_name": "test",
  "display": "standalone",
  "start_url": "/"
}

Thêm file manifest vào index.html

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

Hàm kiểm tra trong main.js

checkIsWebPushSupported() sẽ kiểm tra trình duyệt có hỗ trợ Notification, serviceWorker, pushManager và cập nhật text của button pushButton.

async function checkIsWebPushSupported() {
  let str = '';
  if (!('Notification' in window)) {
    pushButton.textContent = 'Notification Not Supported';
    return false;
  } else if (!('serviceWorker' in navigator)) {
    pushButton.textContent = 'Service worker Not Supported';
    return false;
  } else {
    try {
      const sw = await navigator.serviceWorker.ready;
        if (!('pushManager' in sw)) {
          pushButton.textContent = 'Push Manager Not Supported';
          return false;
        }
        return true;
    } catch (error) {
      str += ('Error when check supported: ' + error + '\n');
      consoleBlock.innerText = consoleBlock.innerText + str;
      pushButton.textContent = 'Error supported';
      return false;
    }
  }
}

Đăng ký service worker trong main.js

handleLoading() sẽ đăng ký file sw.js là service worker sau khi đã kiểm tra trình duyệt có hỗ trợ push notification. Thực hiện thay đổi giao diện sau đã đăng ký thành công.

async function handleLoading() {
  if (checkIsWebPushSupported) {
    if (window.navigator.serviceWorker !== undefined) {
      await window.navigator.serviceWorker.register('/sw.js')
      .then(function(swReg) {
        let str = ('Service Worker is registered\n');

        console.log('Service Worker is registered', swReg)

        swRegistration = swReg;
        initializeUI();
        consoleBlock.innerText = consoleBlock.innerText + str;
      })
      .catch(function(error) {
        let str = ('Service Worker Error: ' + error + '\n');
        consoleBlock.innerText = consoleBlock.innerText + str;
      });
    }
  } else {
    return;
  }
}

Hàm khởi tạo giao diện trong main.js

initializeUI() sẽ kiểm tra xem người dùng đã đăng ký cho phép thông báo chưa, cập nhật hành động của button pushButton theo isSubscribed và cập nhật thông tin lên server (trong demo không có).

function initializeUI() {
  let strConsole = '';
  pushButton.addEventListener('click', function() {
    pushButton.disabled = true;
    if (isSubscribed) {
      unsubscribeUser();
    } else {
      subscribeUser();
    }
  });

  // Set the initial subscription value
  navigator.serviceWorker.ready.then((serviceWorkerRegistration) => {
    serviceWorkerRegistration.pushManager.getSubscription()
    .then(function(subscription) {
      isSubscribed = !(subscription === null);

      updateSubscriptionOnServer(subscription);

      if (isSubscribed) {
        strConsole += 'User IS subscribed.\n';
      } else {
        strConsole += 'User is NOT subscribed.\n';
      }
      consoleBlock.innerText = consoleBlock.innerText + strConsole;

      updateBtn();
    })
  });
  consoleBlock.innerText = consoleBlock.innerText + strConsole;
}

Hàm cập nhật trạng thái button pushButton trong main.js

updateBtn() kiểm tra người dùng có cho phép gửi thông báo không và update text, trạng thái của button pushButton theo isSubscribed.

function updateBtn() {
  let strConsole = '';
  strConsole += (window.Notification.permission + '\n');
  if (window.Notification.permission === 'denied') {
    pushButton.textContent = 'Push Messaging Blocked';
    pushButton.disabled = true;
    updateSubscriptionOnServer(null);
    return;
  }

  if (isSubscribed) {
    pushButton.textContent = 'Disable Push Messaging';
  } else {
    pushButton.textContent = 'Enable Push Messaging';
  }

  pushButton.disabled = false;
  consoleBlock.innerText = consoleBlock.innerText + strConsole;
}

Hàm đăng ký người dùng cho phép nhận thông báo trong main.js

  • userVisibleOnly là tham số đảm bảo rằng sẽ hiển thị thông báo mỗi khi được gửi tới và nó phải là true.
  • applicationServerKeyapplicationServerPublicKey được chuyển đổi thành dạng Uint8Array thông qua hàm urlB64ToUint8Array().
  • Nếu người dùng không cung cấp quyền nhận thông báo thì subscribe() sẽ lỗi.
function subscribeUser() {
  let strConsole = '';
  const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
  swRegistration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: applicationServerKey
  })
  .then(function(subscription) {
    strConsole += ('User is subscribed\n');
    consoleBlock.innerText = consoleBlock.innerText + strConsole;

    updateSubscriptionOnServer(subscription);

    isSubscribed = true;

    updateBtn();
  })
  .catch(function(error) {
    strConsole += ('Failed to subscribe the user: ' + error + '\n');
    consoleBlock.innerText = consoleBlock.innerText + strConsole;
    updateBtn();
  });
}

Xử lý sự kiện nhận thông báo trong sw.js

Trình duyệt nhận được thông báo sẽ tìm ra thông báo đó dành cho service worker nào, gọi service worker đó và hiện thông báo đó thông qua showNotification(). showNotification() yêu cầu bắt buộc thuộc tính title.

self.addEventListener('push', function(event) {
  console.log('[Service Worker] Push Received.');
  console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);

  const title = 'Push Codelab';
  const options = {
    body: event.data.text(),
    icon: 'images/icon.png',
    badge: 'images/badge.png'
  };

  const notificationPromise = self.registration.showNotification(title, options);
  event.waitUntil(notificationPromise);
});

Xử lý sự kiện click vào thông báo trong sw.js

Bắt sự kiện notificationclick khi thông báo hiện lên sẽ đóng thông báo và kiểm tra xem trình duyệt có đang mở url đặt trước không. Nếu có thực hiện focus vào url đó, nếu không thì mở url đó lên.

self.addEventListener('notificationclick', function(event) {
  console.log('[Service Worker] Notification click received.');

  event.notification.close();

  event.waitUntil(
    clients
      .matchAll({
        type: "window",
      })
      .then((clientList) => {
        for (const client of clientList) {
          console.log("focus", client.url);
          if (client.url === "/" && "focus" in client) return client.focus();
        }
        if (clients.openWindow) return clients.openWindow("/");
      })
  );
});

Thực hiện gửi thông báo cho người dùng

Truy cập vào website https://web-push-codelab.glitch.me/ dán thông tin sau khi đăng ký xong ở trên màn hình gồm (endpoint, expirationTime, keys) vào phần Subscription to Send To. Nhập nội dung muốn gửi đến vào phần Text to Send và nhấn "SEND PUSH MESSAGE"

get public key

Hàm hủy đăng ký cho phép gửi thông báo trong main.js

function unsubscribeUser() {
  let strConsole = '';
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    if (subscription) {
      return subscription.unsubscribe();
    }
  })
  .catch(function(error) {
    strConsole += ('Error unsubscribing' + error + '\n');
    consoleBlock.innerText = consoleBlock.innerText + strConsole;
  })
  .then(function() {
    updateSubscriptionOnServer(null);

    strConsole += ('User is unsubscribed.\n');
    consoleBlock.innerText = consoleBlock.innerText + strConsole;
    isSubscribed = false;

    updateBtn();
  });
}

Tài liệu tham khảo

push-notification's People

Watchers

 avatar Ngô Việt Hoàng avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.