[Next.js] FCM을 이용한 React 컴포넌트 상태 업데이트

Rachaen·2023년 5월 19일
0

[Frontend] 이것저것

목록 보기
5/7

FCM을 사용하여 푸시 알람을 받아 React 컴포넌트의 상태를 업데이트를 해봅시다!
그 전에 저는 BroadcastChannel을 사용하는 방법으로 구현하였기 때문에 BroadcastChannel에 대해서 집고 가겠습니다.

BroadcastChannel

웹 브라우저에서 간단하게 사용할 수 있는 강력한 통신 메커니즘이며, 동일한 출처의 서로 다른 컨텍스트 간에 메세지를 전송하고 수신하는 기능을 제공합니다.
간단하게 말하자면 하나의 브라우저 탭에서 다른 탭으로, 서비스 워커로 메세지를 전송하거나 수신하는 등의 작업을 수행할 수 있게 해줍니다.

서비스워커와 웹 페이지는 서로 독립적입니다. 그렇기 때문에 하나의 컨텍스트에서 직접적으로 다른 컨텍스트의 변수나 함수에 접근할 수 없고 특정 API를 통해서만 통신할 수 있습니다!
저는 그 중 BroadcastChannel를 이용하여 구현하였습니다.

BroadcastChannel 기본적인 사용방법

// 새로운 채널 생성
const bc = new BroadcastChannel('채널이름');
// 메세지 전송
bc.postMessage('메세지!!');
// 메세지를 수신합니다.
bc.onmessage = function (ev) { console.log(ev); }
// 채널을 닫습니다.
bc.close();

서비스워커 설정


서비스 워커가 push 알림을 받으면 알림 데이터를 BroadcastChannel로 보내, 이를 메인 스레드에서 사용할 수 있게 하는 방법으로 하였습니다.

self.addEventListener('push', function (e) {
  const bc = new BroadcastChannel('fcm_channel');
  console.log('push: ', e.data.json());
  if (!e.data.json()) return;

  const resultData = e.data.json();
  const notificationTitle = resultData.notification.title;
  const notificationOptions = {
    body: resultData.notification.body,
    data: resultData.data,
    ...resultData,
  };

  e.waitUntil(
    self.registration.showNotification(notificationTitle, notificationOptions),
  );

  bc.postMessage(resultData);
});

컴포넌트에서 FCM 설정

컴포넌트에서 Firebase를 초기화하고, 알림을 받기 위해서 사용자의 권한을 요청한다.
후에 BroadcastChannel을 구독하여 새 알림을 받을 수 있도록 하였습니다.

import { initializeApp } from 'firebase/app';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';

const Business = () => {
  const [renderKey, setRenderKey] = useState(0);
    const channel = new BroadcastChannel('fcm_channel');	// BroadcastChannel 구독
    channel.onmessage = function (e) {
      setRenderKey(prevKey => prevKey + 1);
	};
  }, []);
// 나머지 코드
};
export default Business;

푸시 알림에 따른 컴포넌트 상태 업데이트

// AfterOpen.js
const AfterOpen = ({ renderKey }) => {
  useEffect(() => {
   	// renderKey의 변경을 감지하여 필요한 동작을 수행합니다.
  }, [renderKey]);
};

export default AfterOpen;

profile
개발을 잘하자!

0개의 댓글