Push notification lên Browser bằng Reactjs + Nodejs

Tram Ho

Gần đây mình có nghe một người bạn kể về một task trong công việc đó là làm sao để bắn thông báo cho ng dùng thông qua browser . Lúc đấy vs mình thì khái niệm này khá mơ hồ và mình cho rằng nếu đã tắt tab ứng dụng rồi thì làm sao bắn đc Notification chứ. Rồi mình thử tìm hiểu xem có thực sự làm đc chuyện đấy không . Bài viết này mình sẽ chia sẻ các thức hoạt động cũng như một ví dụ minh họa nhỏ mà mình tìm hiểu và làm được về Push notification .

À hóa ra là nó đây thứ mà bấy lâu nay mình nghĩ nó là quảng cáo và nhấn vào Block mà chẳng mảy may suy nghĩ nó thực sự là gì. Không dài dòng thêm nữa chúng ta cùng bắt đầu tìm hiểu về nó nào

Service Worker

Ủa ủa đang tìm hiểu về Push notification lên browser cơ mà. Vâng mình ko nhầm bài viết đâu ạ. Đầu tiên phải tìm hiểu Service Worker trước đã, Service Worker là một script hoạt động ngầm trên browser ( browser underground ) mà không có sự tương tác của người dùng . Ngoài ra, nó giống như một proxy hoạt động ở phía người dùng.

Chúng ta có thể làm gì với Service Worker?

  • Kiểm soát Network Traffic!
  • Cache lại dữ liệu req/res từ đó có thể chạy web offline
  • Thực hiện một số tính năng chạy background như: Push notification và background synchronization.
  • Service Worker chỉ có thể làm việc trên giao thức HTTPS. Bạn cũng có thể làm việc trên localhost trong quá trình phát triển.

Trong bài này thì mình chỉ tập trung vào phần Push notification thôi nhé . Đầu tiên chúng ta cần nắm rõ hoạt động Push này có 2 phần:

  • Push : việc gửi thông báo từ máy chủ đến ứng dụng. vì thế bạn sẽ cần một server
  • Notification : thông báo được hiển thị trên thanh trạng thái của điện thoại hoặc trên browser.

Web push notifications flow

Chúng ta sẽ có 4 tác nhân chính trong quá trình này :

  • User : Ng dùng muốn nhận thông báo
  • Application : Ứng dụng chạy ở phía ng dùng
  • Service worker : Chạy trên browser
  • Push Server : Server bắn tin nhắn đến service workers

Giải thích flow :

1, Luồng bắt đầu khi ứng dụng yêu cầu người dùng đồng ý hiển thị notifications ( giống như ảnh ban đầu ý ). User sẽ có một vài kịch bản có thể xảy ra :

  • Do nothing : default và như vậy thì notification sẽ ko hiện ra
  • Grant : granded notification sẽ có thể hiển thị
  • Deny : denied notification sẽ ko hiện ra

2, 3, Sau khi người dùng đồng ý nhận notifications ứng dụng sẽ register một service worker

4, 5, 6, Sau khi đăng kí thành công sẽ tiến hành tạo push notification subscription

7, Sau đó ứng dụng sẽ gửi đến server . Tất nhiên là server cần phải có 1 endpoint subscription để gửi noti

8, Sau đó server sẽ lưu subcription đó

9, Sau đó Serer có thể gửi notification đến service worker .

10, 11, 12, Service sẽ hiển thị cho ng dùng . Sau đó nếu ng dùng nhấn vào notification đấy server worker sẽ nhận được hành động đó thông quá notification click event. Sau đó nó có thể kích hoạt một số kịch bản như hiển thị trang web , gọi API , v..v….

Code tí vận động ngón tay nào

Ví dụ này mình sẽ làm bằng NodejsReactjs vì thế mặc định là mọi người có một số kiến thức cũng như môi trường cài đặt nhé .

Tạo server

Vẫn những câu lệnh quen thuộc tạo một server nodejs + express và lần này có thêm một thư viện web-push

tạo file index.js

tạo file subscriptionHandler.js để handle việc push notification phía server

Kịch bản

Server này chúng ta tạo 2 api POST /subscriptionGET /subscription/:id để đăng kí và kích hoạt push notification từ phía server tất nhiên là phần GET có thể đc kích hoạt bằng những xử lý logic trong project thực sự như khi có thêm sản phẩm mới ở web bán hàng chứ ko phải client gọi api để bắn notification về mình.

Hơn nữa mình cũng ko dùng database nào nên dữ liệu sẽ đc fix cứng trong function sendPushNotification . Danh sách các client đăng kí cũng đc lưu trong obj subscriptions và phân biệt vs nhau bằng id đc generate từ function createHash

Như vậy là đã xong phần server rồi .

Tạo React app

Cách nhanh nhất để tạo khởi tạo React là chạy lệnh create-react-app:

Mình install luôn thư viện axios để tiện request đến server thay vì fetch
serve để chạy web trên file build

Chú ý

Mặc dù có thể chạy service worker ở local nhưng react yêu cầu phải chạy từ file build. Vì thế chạy service worker trên React thì phải chạy build rồi start bằng lệnh . Hơn nữa vì service worker có cache lại nên để test chuẩn nhất thì nên thỉnh thoảng xóa cache của browser .

Tạo file usePushNotifications.js ( một custom Hook )

Nhiều code thế @@

  • Đầu tiên là check browser có support push notification không
  • Nếu push notifications đã được support tiến hành registers service worker
  • Handler click bằng onClickAskUserPermission để yêu cầu ng dùng cung cấp quyền
  • Handler click bằng onClickSubscribeToPushNotification để tạo push notification subscription
  • Handler click bằng onClickSendSubscriptionToPushServer để gửi push subscription đến server
  • Handler click bằng onclickSendNotification để mô phỏng việc server gửi notification cho mình

Tiếp theo thêm một vài function vào serviceWorker.js file này đã đc tạo sẵn rồi

Chú thích : chúng ta thêm các hàm

  • askUserPermission để xin quyền của user
  • isPushNotificationSupported để check browser có hỗ trợ ko ( cái này sẽ check đc ví dụ mở ẩn danh sẽ ko hỗ trợ )
  • pushServerPublicKey của server
  • createNotificationSubscription để tạo Notification Subscription mà chúng ta đã tạo sự kiện onClickSusbribeToPushNotificationusePushNotifications.js bên trên

Mấu chốt để bắn noti về browser

Để tạo chúng ta cần 2 tham số

  • userVisibleOnly : giá trị kiểu Boolean chỉ ra push subscription được server lại sẽ chỉ được sử dụng để hiển thị cho người dùng .
  • applicationServerKey : là một Base64-encoded DOMString hoặc ArrayBuffer chứa ECDSA P-256 public key mà server push notification sau sẽ dùng để xác thực .

Đây chính là những gì mà hàm createNotificationSubscription tạo ra và chúng ta dùng để register trên server.

  • endpoint : là endpoint duy nhất mang tính chất duy nhất và được sử dụng để định tuyến tin nhắn mà server gửi đến đúng thiết bị .
  • keys: dùng để xác thực và giải mã tin nhắn

Vậy còn khi server push thì phía browser sẽ nghe ở đâu ? . Đó chính là chúng ta phải ghi đè vào file service-worker.js . Thực ra file serviceWorker.js mà create-react-app tạo sẵn ko phải là service-worker.js mà browser chạy ngầm mà sau khi build xong file đấy mới thực sự xuất hiện .

Vì thế chúng ta phải code thêm file sw.js cùng cấp vs file serviceWorker.js

Mục đích là để lắng nghe event và handle việc ng dùng click vào notification đấy. Sau đó sửa lại một chút phần file package.js phần build và thêm lệnh sw ở dưới để nối file sw vào file service-worker.js .

Cuối cùng là phần giao diện .Mình sẽ tận dụng luôn file App.js làm demo

nhớ cuối cùng là chạy lệnh :

Demo : sau khi nhấn 3 nút từ trên xuống dưới và nhấn nút cuối cùng để kích hoạt bắn notification về browser

Link github : https://github.com/vinhyenvodoi98/Push_Notification_Nodejs_Reactjs

Reference :

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo