
지난 포스팅에서 다룬 기본적인 푸시알림 권한 요청에 이어, 이번에는 좀 더 깊이 있는 내용을 다뤄보려고 합니다. 특히 여러 계정을 사용하는 경우의 토큰 관리 방법과 알림 설정 동기화에 대해 자세히 알아보겠습니다.
푸시알림을 구현할 때 가장 중요한 것이 FCM(Firebase Cloud Messaging) 토큰입니다.
이 토큰은 특정 디바이스를 식별하는 고유한 키로, 푸시알림을 보낼 때 사용됩니다.
// FCM 토큰 발급 예시
const token = await Notifications.getExpoPushTokenAsync({
projectId: "your-project-id" // Expo 프로젝트 ID 필요
});
console.log("Device Token:", token.data);
디바이스 단위로 발급
토큰 수명
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를 설계하면 한 디바이스에서 여러 계정의 토큰을 관리할 수 있습니다.
// 로그인 성공 시 토큰 업데이트
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);
}
};
새 계정으로 로그인 시
// 1. 기존 토큰 비활성화
await deactivateOldTokens(deviceToken);
// 2. 새 토큰-계정 매핑 생성
await createNewTokenMapping(userId, deviceToken);
로그아웃 시
// 현재 계정의 토큰만 비활성화
await deactivateUserToken(userId, deviceToken);
interface NotificationSettings {
matchConfirm: boolean; // 매치 확정 알림
matchChange: boolean; // 매치 변경 알림
announcement: boolean; // 공지사항 알림
marketing: boolean; // 마케팅 알림
}
// 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);
}
};
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);
}
};
토큰 만료 상황
네트워크 오류 상황
디바이스 변경 상황