FCM을 사용하여 푸시 알람을 받아 React 컴포넌트의 상태를 업데이트를 해봅시다!
그 전에 저는 BroadcastChannel을 사용하는 방법으로 구현하였기 때문에 BroadcastChannel에 대해서 집고 가겠습니다.
웹 브라우저에서 간단하게 사용할 수 있는 강력한 통신 메커니즘이며, 동일한 출처의 서로 다른 컨텍스트 간에 메세지를 전송하고 수신하는 기능을 제공합니다.
간단하게 말하자면 하나의 브라우저 탭에서 다른 탭으로, 서비스 워커로 메세지를 전송하거나 수신하는 등의 작업을 수행할 수 있게 해줍니다.
서비스워커와 웹 페이지는 서로 독립적입니다. 그렇기 때문에 하나의 컨텍스트에서 직접적으로 다른 컨텍스트의 변수나 함수에 접근할 수 없고 특정 API를 통해서만 통신할 수 있습니다!
저는 그 중 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);
});
컴포넌트에서 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;