Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.devkor.ifive.nadab.domain.notification.application;

import com.devkor.ifive.nadab.domain.notification.application.event.BadgeSyncEvent;
import com.devkor.ifive.nadab.domain.notification.application.event.NotificationCreatedEvent;
import com.devkor.ifive.nadab.domain.notification.core.entity.Notification;
import com.devkor.ifive.nadab.domain.notification.core.entity.NotificationGroup;
Expand Down Expand Up @@ -207,9 +208,9 @@ public void sendTestNotification(Long userId, String title, String body) {

/**
* 다른 기기로 뱃지 개수 동기화 (Silent Badge Update)
* - 비동기로 즉시 실행 (실시간 동기화)
* - 이벤트 발행 (트랜잭션 커밋 후 실행)
*/
private void syncBadgeCount(Long userId) {
fcmNotificationSender.sendSilentBadgeUpdate(userId);
eventPublisher.publishEvent(new BadgeSyncEvent(userId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.devkor.ifive.nadab.domain.notification.application.event;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
* 뱃지 동기화 이벤트
* - 알림 읽음/삭제 후 다른 기기로 뱃지 개수를 동기화할 때 사용
* - 트랜잭션 커밋 후 처리 (AFTER_COMMIT)
*/
@Getter
@RequiredArgsConstructor
public class BadgeSyncEvent {

private final Long userId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,16 @@ public void handleNotificationCreated(NotificationCreatedEvent event) {
transactionHelper.markAsFailed(notificationId);
}
}

/**
* 뱃지 동기화 이벤트 처리
* - AFTER_COMMIT: 알림 읽음/삭제 트랜잭션이 커밋된 후 실행
* - @Async: 비동기로 다른 기기에 뱃지 카운트 동기화
*/
@Async("fcmTaskExecutor")
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleBadgeSync(BadgeSyncEvent event) {
log.debug("Badge sync event received: userId={}", event.getUserId());
fcmSender.sendSilentBadgeUpdate(event.getUserId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ private boolean sendDailyWriteNotification(User user, List<UserDevice> devices)

// 4. FCM 푸시 발송
NotificationMessageDto messageDto = NotificationMessageDto.builder()
.notificationId(null) // 알림함에 저장하지 않음
.type(NotificationType.DAILY_WRITE_REMINDER)
.title(content.title())
.body(content.body())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ private boolean sendInactiveUserNotification(

// 5. FCM 푸시 발송
NotificationMessageDto messageDto = NotificationMessageDto.builder()
.notificationId(null) // 알림함에 저장하지 않음
.type(NotificationType.INACTIVE_USER_REMINDER)
.title(content.title())
.body(content.body())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
@Builder
public class NotificationMessageDto {

private Long notificationId; // 푸시 알림 탭 시 읽음 처리용
private NotificationType type;
private String title;
private String body;
Expand All @@ -21,6 +22,7 @@ public class NotificationMessageDto {

public static NotificationMessageDto from(Notification notification, int unreadCount) {
return NotificationMessageDto.builder()
.notificationId(notification.getId())
.type(notification.getType())
.title(notification.getTitle())
.body(notification.getBody())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public List<String> sendMulticast(List<String> fcmTokens, NotificationMessageDto
.setTitle(message.getTitle())
.setBody(message.getBody())
.build())
.putData("notificationId", String.valueOf(message.getNotificationId()))
.putData("type", message.getType().name())
.putData("targetId", message.getTargetId() != null ? message.getTargetId() : "")
.putData("inboxMessage", message.getInboxMessage())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,9 @@ private Map<Long, Map<NotificationGroup, Boolean>> loadNotificationSettings(List

/**
* Silent Badge Update (알림 없이 뱃지만 업데이트)
* - 알림 읽음/삭제 후 다른 기기 뱃지 동기화
* - 비동기로 즉시 실행 (실시간 동기화)
* - EventListener에서 호출 (다른 기기 뱃지 동기화)
* - Multicast 발송
*/
@Async("fcmTaskExecutor")
public void sendSilentBadgeUpdate(Long userId) {
// 사용자 조회
User user = userRepository.findById(userId).orElse(null);
Expand Down
Loading