React Native Expo 푸시알림 구현하기 (2) - 토큰 관리와 설정 동기화

oversleep·2025년 2월 15일
0

app-development

목록 보기
8/38
post-thumbnail

들어가며

지난 포스팅에서 다룬 기본적인 푸시알림 권한 요청에 이어, 이번에는 좀 더 깊이 있는 내용을 다뤄보려고 합니다. 특히 여러 계정을 사용하는 경우의 토큰 관리 방법과 알림 설정 동기화에 대해 자세히 알아보겠습니다.

FCM 토큰의 이해

푸시알림을 구현할 때 가장 중요한 것이 FCM(Firebase Cloud Messaging) 토큰입니다.
이 토큰은 특정 디바이스를 식별하는 고유한 키로, 푸시알림을 보낼 때 사용됩니다.

FCM 토큰의 특징

// FCM 토큰 발급 예시
const token = await Notifications.getExpoPushTokenAsync({
  projectId: "your-project-id" // Expo 프로젝트 ID 필요
});
console.log("Device Token:", token.data);
  1. 디바이스 단위로 발급

    • 하나의 기기에는 하나의 FCM 토큰만 존재
    • 앱을 재설치하거나 토큰이 만료되면 새로운 토큰 발급
    • 토큰은 앱 설치 시 또는 푸시 권한 허용 시 생성
  2. 토큰 수명

    • 보통 장기간 유효하지만 영구적이지는 않음
    • 사용자가 앱을 재설치하거나
    • 오랜 기간 앱을 사용하지 않으면 토큰 만료 가능

멀티 계정 상황에서의 토큰 관리

1. 토큰-계정 매핑 테이블 설계

CREATE TABLE user_tokens (
    id SERIAL PRIMARY KEY,
    user_id VARCHAR NOT NULL,
    device_token VARCHAR NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    is_active BOOLEAN DEFAULT true
);

이런 구조로 DB를 설계하면 한 디바이스에서 여러 계정의 토큰을 관리할 수 있습니다.

2. 토큰 업데이트 로직

// 로그인 성공 시 토큰 업데이트
const updateDeviceToken = async (userId: string) => {
  try {
    const token = await Notifications.getExpoPushTokenAsync();
    
    // 서버에 토큰 업데이트 요청
    await axios.post('/api/update-token', {
      userId,
      deviceToken: token.data,
    });
    
  } catch (error) {
    console.error('토큰 업데이트 실패:', error);
  }
};

3. 토큰 관리 시나리오

  1. 새 계정으로 로그인 시

    // 1. 기존 토큰 비활성화
    await deactivateOldTokens(deviceToken);
    
    // 2. 새 토큰-계정 매핑 생성
    await createNewTokenMapping(userId, deviceToken);
  2. 로그아웃 시

    // 현재 계정의 토큰만 비활성화
    await deactivateUserToken(userId, deviceToken);

알림 설정 동기화

1. 설정 저장 구조

interface NotificationSettings {
  matchConfirm: boolean;  // 매치 확정 알림
  matchChange: boolean;   // 매치 변경 알림
  announcement: boolean;  // 공지사항 알림
  marketing: boolean;     // 마케팅 알림
}

2. 설정 저장 방식

// AsyncStorage에 설정 저장
const saveNotificationSettings = async (settings: NotificationSettings) => {
  try {
    await AsyncStorage.setItem(
      'notification_settings',
      JSON.stringify(settings)
    );
    
    // 서버에도 설정 동기화
    await axios.post('/api/notification-settings', settings);
  } catch (error) {
    console.error('설정 저장 실패:', error);
  }
};

3. 계정 전환 시 설정 동기화

const syncNotificationSettings = async (userId: string) => {
  try {
    // 서버에서 해당 사용자의 설정 가져오기
    const response = await axios.get(`/api/notification-settings/${userId}`);
    const serverSettings = response.data;
    
    // 로컬 저장소에 설정 저장
    await AsyncStorage.setItem(
      'notification_settings',
      JSON.stringify(serverSettings)
    );
  } catch (error) {
    console.error('설정 동기화 실패:', error);
  }
};

고려해야 할 엣지 케이스

  1. 토큰 만료 상황

    • 주기적으로 토큰 유효성 검사
    • 만료 시 새 토큰 발급 및 업데이트
  2. 네트워크 오류 상황

    • 오프라인 상태에서의 설정 변경 처리
    • 재접속 시 설정 동기화
  3. 디바이스 변경 상황

    • 새 디바이스에서 로그인 시 설정 복구
    • 이전 디바이스의 토큰 처리
profile
궁금한 것, 했던 것, 시행착오 그리고 기억하고 싶은 것들을 기록합니다.

0개의 댓글