[FCM]firebase FCM 웹 푸시알람

코드왕·2024년 11월 21일
  1. FIREBASE VAPID KEY 만들기

  1. WEB API KEY 정보들 받기

  1. Nextjs에서 firebase 앱을 실행하고 service worker를 만들자
//public/firebase-messaging-sw.js

importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-messaging-compat.js');

firebase.initializeApp({
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: ""
});

const messaging = firebase.messaging();

messaging.onBackgroundMessage(function(payload) {
  console.log('Received background message ', payload);

  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
    icon: '/images/logo-new.png'
  };

  return self.registration.showNotification(notificationTitle, notificationOptions);
});
  1. 등록 시 fcmToken을 저장하게 하자
//page.js

// Firebase 설정 및 초기화 추가
const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};

// Firebase 앱 초기화
const app = initializeApp(firebaseConfig);

export default function Component() {
  // Firebase 초기화 후에 service worker 등록 및 알림 권한 요청
  useEffect(() => {
    const registerServiceWorker = async () => {
      if ('serviceWorker' in navigator && typeof window !== "undefined") {
        try {
          const registration = await navigator.serviceWorker.register('/firebase-messaging-sw.js');
          console.log('Service Worker registered with scope:', registration.scope);
          
          // 알림 권한 요청
          const permission = await Notification.requestPermission();
          console.log('Notification permission status:', permission);
        } catch (error) {
          console.error('Service Worker registration failed:', error);
        }
      }
    };

    registerServiceWorker();
  }, []);  
  
  const handleRegister = async () => {
    if (password !== passwordConfirm) {
      console.error("Passwords do not match");
      toast("비밀번호가 일치하지 않습니다.");
      return;
    }

    try {
      let fcmToken = null;

      // FCM 토큰 획득 시도 (수정된 부분)
      if ('serviceWorker' in navigator && Notification.permission === 'granted') {
        
          const messaging = getMessaging(app);
          fcmToken = await getToken(messaging, {
            vapidKey: process.env.NEXT_PUBLIC_FIREBASE_VAPID_KEY,
            serviceWorkerRegistration: await navigator.serviceWorker.getRegistration()
          });
          console.log('FCM Token:', fcmToken);
      }

      // Supabase 회원가입 진행
      const { data, error } = await supabase.auth.signUp({
        email,
        password,
      });

      if (error?.message.toLowerCase().includes("already")) {
        toast.error("이미 가입된 이메일입니다.");
        return;
      }

      // 3. 프로필 정보와 FCM 토큰 저장
      const userId = data.user.id;
      const { error: updateError } = await supabase
        .from("profiles")
        .update({
          nickname,
          email,
          blog,
          naver,
          fcmToken: fcmToken, // FCM 토큰 추가
        })
        .eq("id", userId);

      if (updateError) {
        console.error("Profile update error:", updateError);
        toast.error("프로필 업데이트 중 오류가 발생했습니다.");
        return;
      }

      router.push("/login?register=success");
    } catch (error) {
      console.error("Registration error:", error);
      toast.error("회원가입 중 오류가 발생했습니다.");
    }
  };
  
}
  1. 테스트 해보자

profile
CODE DIVE!

0개의 댓글