엘리스 AI트랙 4기/프로젝트

[PWA] Push Notification 튜토리얼 따라해보기

남쪽마을밤송이 2022. 7. 11. 03:24

 [ 01 튜토리얼 선택 ] 

 (1) 영상 소개 

  • 이 자리를 빌어 나를 구원해 준 인상 좋은 개발자님께 감사의 인사를 드린다... 2일째 밤까지 아무 진전이 없어 좌절감만 느끼고 있었는데 이 분이 그나마 알아듣기 쉬운 영국st 억양에 web push? 그거 정말 별 것도 아니라는 말투로 설명해주셔서 들어봤는데 복잡했던 개념이 이 짧은 영상으로 정리됐다. 게다가 다른 tutorial들과 다르게 진짜 딱 푸시 알림 하나 보내기 위해 필요한 코드만 있어서 완전 강력 추천😍
  • 소스코드 : https://github.com/MarkJamesHoward/push

 (2) web-push 

  • 위 영상의 유튜버도 그렇고 블로그들을 찾아봤을 때도 그렇고 꽤 많은 nodejs 사용자가  web-push 라는 npm package를 사용하는 듯 했다.
  • 해당 패키지는 몇 개의 메소드만으로 FCM 푸시 알림을 쉽게 사용할 수 있도록 도와주는데, FCM의 자체 로직을 완벽히 이해하고 싶다면 패키지 대신 Firefox가 제공하는  firebase-admin  package를 install하고 Cloud Messaging API를 사용하면 된다.
    • 관련 블로그들과 자료도 꽤 있으니 이제는(!!) 어렵지 않을 것 같지만 처음엔 서비스 구조와 동작 방식도 이해가 되지 않는데 Firefox의 방대한 FCM 공식문서에 뒷걸음질 치며 + 유일하게 이해한 유튜브 강의를 따라 패키지 사용을 택했다.
    • 사실 이해하고 보니 별 차이 없는 것 같아서 시간 상관없이 학습이 목표라면 firebase-admin으로 직접 사용하는 걸 추천한다.

 (3) 전체적인 로직 

  • 아래 UML 시퀀스 다이어그램은 위 github repository 코드의 파일명과 web-push 패키지의 메소드명을 기준으로 작성되었다. FCM 메소드와는 차이가 있음에 주의한다.

  • 설명
  1. 사용자(User)가 웹 페이지(index.html)에 접속하면 serviceWorker와 pushManager 사용이 가능한지 체크 한다.
  2. 사용 가능하다면 service worker 파일인 sw.js를 등록(register)한다.
    • 등록된 서비스워커는 생명주기에 따라 다운로드 설치  활성화 될 것이다.
  3. 사용자가 구독 버튼을 누르면 pushManager.subscribe()로 구독하고 사용자의 디바이스 토큰 정보를 반환한다.
    • 코드에는 없지만 실서비스에서는 여기서 Database에 디바이스 토큰을 저장하고 사용하면 된다.
  4. push.js 파일에서 setVapidDetails()로 공개키, 비밀키를 설정 하고 원하는 내용으로 푸시 알림 내용을 작성한 뒤 파일을 실행하면 sendNotification() 메소드가 "push" 이벤트를 발생시킨다.
  5. addEventListener로 "push" 이벤트를 듣고 있던 중인 Service Worker가 sendNotification 정보대로 푸시 알림을 발생시킨다. (showNotification)
  • 이 로직만 이해하면 나도 이제 web-push 마스터~는 아니고 절반쯤 가능이다.

 

 [ 02 튜토리얼 따라하기 ] 

 (1) 코드 

  • 코드는 간편하게 git clone으로 다운받았다.
  • 여기서 잠깐, 유튜버님은 디바이스 토큰을 콘솔로만 출력하셨는데 나는 Android 환경에서도 테스트하고 싶었기 때문에 <p> 태그로도 출력하도록 수정했다.
<body>
    <button onclick="subscribe()">Subscribe</button>
    <p id="deviceToken"></p>

    <script>
      subscribe = async () => {
        let sw = await navigator.serviceWorker.ready;
        let push = await sw.pushManager.subscribe({
          userVisibleOnly: true,
          applicationServerKey:
            "public key",
        });
        console.log(JSON.stringify(push));
        const token = document.getElementById("deviceToken");
        token.innerHTML = JSON.stringify(push);
      };

     .
     .
     .
     
    </script>
  </body>

 (2) netlify 

  • 유튜브 보면서 또 새롭게 알아간 한 가지. netlify 사이트이다.
  • 이미 나 몰래 유명했던 것 같은데 front에서 정적 웹사이트를 배포하기에 간편한 사이트라고 한다.
    • 따라서 여기서 back-end를 구현하기에는 굉장히 귀찮고 복잡해보였고 보통 netlify로 FrontEnd 배포 + Heroku나 EC2로 BackEnd 배포 조합을 사용하는 것 같았다.
    • 그런데 내가 프로젝트 중반에 react로 배포해봤는데 메인 화면 뜨는 속도가 굉~~~장히 느렸다. 따라서 간단한 웹사이트 테스트 배포하는데나 사용하는 걸로..!
    • 그래도 사이트 배포 즉시 https를 알아서 적용해주고 CI/CD도 기본으로 동작하는 이점이 있다.
  • 어쨌든 여기서 사용한 이유는 저번 포스팅에서 말했듯이 Service Worker가 https 환경에서만 동작하기 때문인데, localhost에서도 동작하기 때문에 굳이? 싶지만 일단 갓튜버님이 하시는대로 따라했다.

 (3) index.html 페이지 

  • Service Worker가 잘 등록되었는지 보려면  Application 탭의  Service Workers 를 보면 된다.

  • 여기서 중요한 주의할 점!!! Service Worker는 생명주기에 따라 새로운 버전의 코드가 있어도 설치(Install)까지만 하고 바로 활성화하지 않기 때문에 서비스워커 파일(여기서는 sw.js)을 수정할 경우  Update on reload 체크를 켜고 새로고침 해주어야 변경된 소스코드가 적용된다!

  • Update on reload 체크 후 새로고침 하니 방금 전 수정한 버전으로 잘 적용된 것을 확인할 수 있다.

 (4) 구독 성공 

  • Service Worker랑 pushManager를 문제 없이 사용 가능하다면 구독 버튼을 눌렀을 때 디바이스 토큰이 잘 뜨는 걸 볼 수 있다.

 (5) 푸시 알림 

  • 이제 이걸 push.js 파일에서 다음과 같이 적용해준다.
// setVapidDetails()로 공개키, 비밀키 설정
.
.
.

// 여기에 디바이스 토큰 복붙
const gram360 = {
  endpoint:
    "https://fcm.googleapis.com/fcm/send/eJFwqyH7Yag:APA91bEjC05HivhJc2VbxmErm2WH4ymXWbRKjFv~~~~~~~~~~~~~~~~~~~~~~~~~~~VdFLsuShl_HpJm6NXz1-535IKBwQFbyrp",
  expirationTime: null,
  keys: {
    p256dh:
      "BEoFtHjeYseEx_kEYveCYSB~~~~~~~~~~~~~~~~~~~~~~~~~~~~NJ7_33GalWVorYR9ZkAck",
    auth: "ikG2~~~~~~~~~~~q_Cbg",
  },
};

const notification = {
  title: "Hey, this is a push notification!",
  body: "Subscribe Pill my rhythm",
};

// 인자값 subscription, payload, options
webpush.sendNotification(gram360, JSON.stringify(notification));
  • 그리고 터미널에서  node push.js  명령어로 파일을 실행하면 푸시 알림이 온다~!~!

 


  • 푸시 알림 감 잡기 완료😉
  • 이제 다음 포스팅은 이걸 현재 프로젝트에 적용하는 부분이다.