[firebase]FCM으로앱 푸시 알람

코드왕·2024년 11월 22일
  1. 네이티브 혹은 크로스플랫폼에 브릿지를 만들어야됨

네이티브에 요청을 해야한다. 특정 함수를 호출하면 pushToken을 만들도록 해야한다. 그래야 해당 핸드폰으로 알람이 간다

  1. 웹에서 요청을 통해서 응답을 받아야 한다.
    :아이폰인지 안드로이드 인지 useragent로 판단한 다음에 함수를 호출하고 특정 콜백 함수를 만들어놓고 그걸 가져와야 한다.
    :그리고 로그인 할때마다 갱신 시켜주는 것이 좋다. 폰이 바뀌면 알람이 안올 수 있다.

크몽 요청내용

UserAgent :
아래의 정보가 포함되어있으니 “contains” 함수 등으로 체크 부탁드립니다
AOS : 기존 UserAgent 뒤에 “Mom-playground_AOS_APP”
IOS : 기존 UserAgent 앞에 “mom-playground_IOS_APP”

<푸시 토큰 정보 가져오기>
void getFcmInfo()
기능 : Fcm Token 반환
Input : 없음
OutPut : 콜백형 데이터 전달
CallBack :
AOS : function onFcmInfoSuccess(‘token’)
IOS : function onFcmInfoSuccess(‘token’)
token > Fcm Token 값
상세 설명 :
웹 사이트내에 onFcmInfoSuccess메소드를 정의해두신후
웹에서 getFcmInfo()를 호출해주시면. onFcmInfoSuccess 메소드가 콜백됩니다.

브릿지 메소드 호출 방법 예시

** 안드로이드
1. window.mom-playground.getFcmInfo();

** 아이폰
window.webkit.messageHandlers.getFcmInfo.postMessage('');

useEffect(() => {
    // 콜백 함수 등록
    window.onFcmInfoSuccess = (token) => {
      console.log("FCM Token received:", token);
      toast.info(`원본 FCM 토큰: ${token}`);
      setFcmToken(token);
    };

    // 클린업 함수
    return () => {
      window.onFcmInfoSuccess = null;
    };
  }, []); // 빈 의존성 배열로 마운트 시에만 실행

  const requestFcmToken = () => {
    return new Promise((resolve) => {
      const userAgent = navigator.userAgent;
      toast.info(`UserAgent: ${userAgent}`);
      
      if (!userAgent.includes("Mom-playground_AOS_APP") && 
          !userAgent.includes("mom-playground_IOS_APP")) {
        console.log("Not a mobile app environment");
        setFcmToken(null);
        resolve(null);
        return;
      }

      // 먼저 콜백 함수를 설정
      const newCallback = (token) => {
        resolve(token);
      };
      window.onFcmInfoSuccess = newCallback;

      // 그 다음 토큰 요청
      try {
        if (userAgent.includes("Mom-playground_AOS_APP")) {
          
          window.momPlayground.getFcmInfo();
          toast.info("FCM 토큰 요청 중...구글");
        } else {
          window.webkit.messageHandlers.getFcmInfo.postMessage('');
          toast.info("FCM 토큰 요청 중...애플");
        }
      } catch (error) {
        console.error("Error requesting FCM token:", error);
        toast.error("FCM 토큰 요청 중 오류 발생");
        resolve(null);
      }
    });
  };

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

    try {
      // FCM 토큰이 없는 경우에만 요청하고 응답을 기다림
      let currentFcmToken = fcmToken;
      if (!currentFcmToken) {
        currentFcmToken = await requestFcmToken();
      }
      
      // FCM 토큰이 없어도 계속 진행
      toast.success("FCM 토큰:" + currentFcmToken);
      
      // Supabase 회원가입 진행
      const { data, error } = await supabase.auth.signUp({
        email,
        password,
      });

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

      // 프로필 정보와 FCM 토큰 저장
      const userId = data.user.id;
      const { error: updateError } = await supabase
        .from("profiles")
        .update({
          nickname,
          email,
          blog,
          naver,
          fcmToken: currentFcmToken, // 로컬 변수 사용
          updated_at: new Date().toISOString(),
        })
        .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("회원가입 중 오류가 발생했습니다.");
    }
  };
profile
CODE DIVE!

0개의 댓글