Firebase FCM과 Expo기반으로 Push Service 푸시 알림을 받는 앱 만들기

Firebase FCM과 Expo기반으로 Push Service 푸시 알림을 받는 앱 만들기. Expo를 사용한 푸시 알림 앱을 만드는 법을 정리해봤습니다. Firebase Cloud Messaging(FCM)과 Expo의 Push Notification Service를 통해 푸시 알림을 받으며, 수신된 메시지 수만큼 앱 아이콘에 배지를 표시합니다.

1. 프로젝트 생성

먼저, Expo CLI를 사용하여 프로젝트를 생성합니다.

npx create-expo-app PushNotificationApp
cd PushNotificationApp

2. 필요한 라이브러리 설치

expo-notifications는 푸시 알림 처리를 위한 라이브러리입니다. expo-permissions는 푸시 알림 권한을 요청하기 위해 필요합니다.

expo install expo-notifications expo-permissions expo-device

3. Firebase 프로젝트 설정

Firebase 콘솔에서 프로젝트를 생성하고 FCM(Firebase Cloud Messaging) 설정을 완료한 후, google-services.json 파일을 다운로드하여 Android 빌드 시 사용할 준비를 합니다.

Expo의 Managed Workflow는 FCM을 네이티브로 직접 지원하지 않으므로, EAS Build를 사용하여 Firebase 설정을 적용합니다.

4. 프로젝트 구조

다음은 Expo 프로젝트의 기본 구조입니다.

PushNotificationApp/
├── App.js
├── babel.config.js
├── package.json
├── node_modules/
├── assets/
└── .expo/

5. EAS Build 설정

Expo Managed Workflow에서 Firebase를 사용하려면 EAS Build를 설정해야 합니다.

  1. EAS CLI 설치:

    npm install -g eas-cli
  2. EAS 프로젝트 초기화:

    eas build:configure
  3. Firebase에서 받은 google-services.json 파일을 android/app 폴더에 추가하세요. Expo 프로젝트의 루트 디렉토리에는 이 폴더가 없으므로, EAS Build 설정 중에 파일을 올바르게 처리할 수 있도록 설정합니다.

  4. Firebase에서 Push Notification을 사용할 수 있도록 Firebase Cloud Messaging(FCM) 설정을 완료합니다.

6. App.js 파일 작성

이제 App.js 파일을 작성하여 푸시 알림과 배지 설정을 구성합니다.

import React, { useEffect, useState } from "react";
import { View, Text, Button, Platform } from "react-native";
import * as Notifications from "expo-notifications";
import * as Device from "expo-device";
import * as Permissions from "expo-permissions";

export default function App() {
  const [expoPushToken, setExpoPushToken] = useState("");
  const [messageCount, setMessageCount] = useState(0);
  const notificationListener = React.useRef();
  const responseListener = React.useRef();

  useEffect(() => {
    registerForPushNotificationsAsync().then((token) =>
      setExpoPushToken(token)
    );

    // 푸시 알림 수신 리스너
    notificationListener.current =
      Notifications.addNotificationReceivedListener((notification) => {
        handleReceiveMessage();
      });

    // 푸시 알림 클릭 리스너
    responseListener.current =
      Notifications.addNotificationResponseReceivedListener((response) => {
        console.log(response);
      });

    return () => {
      Notifications.removeNotificationSubscription(
        notificationListener.current
      );
      Notifications.removeNotificationSubscription(responseListener.current);
    };
  }, []);

  const handleReceiveMessage = () => {
    setMessageCount((prevCount) => {
      const newCount = prevCount + 1;
      Notifications.setBadgeCountAsync(newCount); // 배지 숫자 업데이트
      return newCount;
    });
  };

  const resetBadge = () => {
    setMessageCount(0);
    Notifications.setBadgeCountAsync(0); // 배지 숫자 초기화
  };

  return (
    <View style={{ padding: 20 }}>
      <Text>Your Expo Push Token: {expoPushToken}</Text>
      <Text>Message Count: {messageCount}</Text>
      <Button title="Reset Badge" onPress={resetBadge} />
    </View>
  );
}

// 푸시 알림 권한 요청 및 토큰 발급
async function registerForPushNotificationsAsync() {
  let token;
  if (Device.isDevice) {
    const { status: existingStatus } =
      await Notifications.getPermissionsAsync();
    let finalStatus = existingStatus;
    if (existingStatus !== "granted") {
      const { status } = await Notifications.requestPermissionsAsync();
      finalStatus = status;
    }
    if (finalStatus !== "granted") {
      alert("Failed to get push token for push notification!");
      return;
    }
    token = (await Notifications.getExpoPushTokenAsync()).data;
    console.log(token);
  } else {
    alert("Must use physical device for Push Notifications");
  }

  if (Platform.OS === "android") {
    Notifications.setNotificationChannelAsync("default", {
      name: "default",
      importance: Notifications.AndroidImportance.MAX,
      vibrationPattern: [0, 250, 250, 250],
      lightColor: "#FF231F7C",
    });
  }

  return token;
}

7. Expo Push Notification 테스트

Expo의 Push Notification Service를 통해 서버에서 푸시 알림을 보낼 수 있습니다. 다음과 같은 명령어로 푸시 알림을 테스트할 수 있습니다.

curl -X POST https://exp.host/--/api/v2/push/send 
  -H "Content-Type: application/json" 
  -d '{
        "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
        "sound": "default",
        "title": "New Message",
        "body": "You have received a new message!",
        "data": { "message": "Hello World" }
      }'

8. EAS 빌드

앱이 실제 기기에서 제대로 작동하려면 EAS 빌드를 사용해야 합니다.

eas build --platform android

EAS 빌드를 완료한 후, 실제 기기에서 빌드된 앱을 테스트하고, Firebase에서 푸시 알림을 전송하여 알림과 배지 숫자가 정상적으로 작동하는지 확인할 수 있습니다.


정리

  1. Expo CLI로 프로젝트 생성
  2. expo-notifications 패키지 설치
  3. Firebase 콘솔에서 프로젝트 생성 및 설정
  4. App.js 파일에서 Expo Push Notification 설정
  5. curl 명령어를 통해 Expo Push Notification Service에서 푸시 알림 테스트
  6. EAS 빌드를 통해 앱을 빌드하고 실제 기기에서 테스트

이 구조로 Expo와 Firebase Push 알림을 사용하는 앱을 완성할 수 있습니다.

Leave a Comment