Home
Hooks

use-fcm

11/14/2025, 3:30:43 AM modified by Marvin

A hook to handle Firebase Cloud Messaging, including token management, permission requests, and message handling.

Installation

Loading...

Notice

  • Please move firebase-messaging-sw.js from src/public to public folder manually.
  • Please replace firebaseConfig in use-fcm/helper.ts with your own Firebase configuration.
const firebaseConfig = {
  // Your own Firebase configuration
};

Preview

Nothing to show.
// @ts-nocheckimport type { MessagePayload } from 'firebase/messaging';import { onMessage as onMessage_ } from 'firebase/messaging';import { useEffect } from 'react';import { getFCMToken, messaging } from './helper';const vapidKey = 'Your Vapid Key';export function useFCM({  onMessage,  onToken,}: {  onMessage?: (payload: MessagePayload) => void;  onToken?: (token: string) => void;}) {  useEffect(() => {    getFCMToken({      vapidKey,    }).then((token) => {      if (token) {        onToken?.(token);      }    });  }, [onToken]);  useEffect(() => {    if (!onMessage) {      return;    }    const unsubscribe = onMessage_(messaging(), onMessage);    return () => unsubscribe();  }, [onMessage]);}
// @ts-nocheckimport { initializeApp } from 'firebase/app';import { type GetTokenOptions, getMessaging, getToken, isSupported } from 'firebase/messaging';import { requestPermission } from '@/lib';const firebaseConfig = {  apiKey: 'AIzaSyCN99e2MFNFCBgZAh4YjbboM7dx4L208cc',  authDomain: 'my-awesome-20250904.firebaseapp.com',  projectId: 'my-awesome-20250904',  storageBucket: 'my-awesome-20250904.firebasestorage.app',  messagingSenderId: '447700238822',  appId: '1:447700238822:web:57170ca06a374c10671627',  measurementId: 'G-L0TVC48MM3',};// Initialize Firebaseconst app = initializeApp(firebaseConfig);// Initialize Firebase Cloud Messaging and get a reference to the serviceexport const messaging = () => getMessaging(app);export async function getFCMToken(params: Pick<GetTokenOptions, 'vapidKey'>) {  const { vapidKey } = params;  const permission = await requestPermission();  if (typeof window !== 'undefined' && 'serviceWorker' in navigator && permission === 'granted') {    try {      if (!(await isSupported())) {        return;      }      return await getToken(messaging(), {        vapidKey,      });    } catch (error) {      console.error('getFCMToken error:', error);    }  }}
const logger = console.log;// some key maybe unnecessary, but keep it for nowconst searchKey = '__s';const searchValue = 'n';const storageKey = 'storageKey';const CHANNEL_NOTIFICATION_KEY = 'NEW_NOTIFICATION';// Create BroadcastChannel for notificationconst notificationChannel = new BroadcastChannel(storageKey);// Must be placed before importScriptsglobalThis.addEventListener('notificationclick', (event) => {  logger('[notificationclick]', event);  if (!event.notification || !event.notification.data) {    return;  }  event.notification.close();  const { FCM_MSG } = event.notification.data;  if (!FCM_MSG) {    return;  }  const { data } = FCM_MSG;  const defaultLink = globalThis.location.origin;  const link = data?.link || defaultLink;  event.waitUntil(    clients.matchAll({ type: 'window', includeUncontrolled: true }).then((windowClients) => {      for (const client of windowClients) {        const clientUrl = new URL(client.url);        const notificationUrl = new URL(link);        if (clientUrl.origin === notificationUrl.origin && 'focus' in client) {          client.postMessage({ [searchKey]: searchValue });          return client.focus();        }      }      return clients.openWindow(`${link}?${searchKey}=${searchValue}`);    }),  );});importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-app-compat.js');importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-messaging-compat.js');importScripts('https://cdnjs.cloudflare.com/ajax/libs/idb-keyval/6.2.2/umd.js');const firebaseConfig = {  apiKey: 'AIzaSyCN99e2MFNFCBgZAh4YjbboM7dx4L208cc',  authDomain: 'my-awesome-20250904.firebaseapp.com',  projectId: 'my-awesome-20250904',  storageBucket: 'my-awesome-20250904.firebasestorage.app',  messagingSenderId: '447700238822',  appId: '1:447700238822:web:57170ca06a374c10671627',  measurementId: 'G-L0TVC48MM3',};// Initialize the Firebase app in the service worker by passing in// your app's Firebase config object.// https://firebase.google.com/docs/web/setup#config-objectfirebase.initializeApp(firebaseConfig);// Retrieve an instance of Firebase Messaging so that it can handle background// messages.const messaging = firebase.messaging();messaging.onBackgroundMessage(async (payload) => {  logger('[firebase-messaging-sw.js] Received background message:', payload);  // Store message to IndexedDB  try {    // Get existing data, keep Zustand's StorageValue structure    const existingData = (await idbKeyval.get(storageKey)) || {      state: {        notifications: [],      },      version: 0,    };    const newNotification = {      ...payload,      createdAt: Date.now(),    };    existingData.state.notifications = [newNotification, ...existingData.state.notifications];    existingData.version = existingData.version || 0;    await idbKeyval.set(storageKey, existingData);    // 通过 BroadcastChannel 通知所有打开的页面同步数据    notificationChannel.postMessage({      type: CHANNEL_NOTIFICATION_KEY,      payload,    });  } catch (_error) {}});

API Reference

FCM (Firebase Cloud Messaging) 工具库提供了一套完整的函数和 React Hook,用于在 Web 应用中集成 Firebase 推送通知功能。

Git Commit History(1 commits)

feat: build

Marvin
11月14日 03:30
e50053c2