Skip to content

Commit

Permalink
[merge]: 푸시 알림 문제 수정 (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
kanguk01 authored Nov 13, 2024
2 parents 4900c9b + 40f0018 commit 791671b
Show file tree
Hide file tree
Showing 10 changed files with 32 additions and 109 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
fi
- name: Build with Gradle
run: ./gradlew build -Dspring.profiles.active=test
run: ./gradlew clean build -Dspring.profiles.active=test

- name: Run Tests
run: ./gradlew test -Dspring.profiles.active=test
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ docker/*.env
!docker/sample.env
docker/.DS_Store

./splanet.log
./splanet-test.log
splanet.log
splanet-test.log
### log ###
logs/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/error").permitAll()
.anyRequest().permitAll()
)
.oauth2Login(oauth2 -> oauth2
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,29 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Component
@RequiredArgsConstructor
public class NotificationScheduler {

private static final ZoneId ZONE_ID_SEOUL = ZoneId.of("Asia/Seoul");
private final PlanRepository planRepository;
private final FcmTokenRepository fcmTokenRepository;
private final NotificationLogRepository notificationLogRepository;
private final NotificationService notificationService;
private final QueryPerformanceService queryPerformanceService;


@Scheduled(fixedRate = 60000)
public void sendScheduledNotifications() {
LocalDateTime now = LocalDateTime.now();
LocalDateTime now = LocalDateTime.now(ZONE_ID_SEOUL);

List<Plan> upcomingPlans = planRepository.findUpcomingPlans(now);

Expand Down Expand Up @@ -67,7 +68,7 @@ public void sendScheduledNotifications() {

for (FcmToken fcmToken : fcmTokens) {
if (Boolean.TRUE.equals(fcmToken.getIsNotificationEnabled())) {
LocalDateTime notificationTime = plan.getStartDate().minusMinutes(fcmToken.getNotificationOffset());
LocalDateTime notificationTime = plan.getStartDate().atZone(ZONE_ID_SEOUL).toLocalDateTime().minusMinutes(fcmToken.getNotificationOffset());

if (notificationTime.isAfter(now.minusMinutes(5)) && notificationTime.isBefore(now.plusMinutes(1))) {
String notificationKey = fcmToken.getId() + ":" + plan.getId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.time.format.DateTimeFormatter;

@Slf4j
@Service
Expand All @@ -29,53 +29,29 @@ public NotificationService(FcmTokenRepository fcmTokenRepository, FirebaseMessag
}

public void sendNotification(FcmToken fcmToken, Plan plan) {
String title = "곧 시작하는 플랜: " + plan.getTitle();
String body = "곧 시작하는 플랜이 있어요! " + plan.getDescription();
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH시 mm분");

String nickname = plan.getUser().getNickname();

String startTime = plan.getStartDate().toLocalTime().format(timeFormatter);
String endTime = plan.getEndDate().toLocalTime().format(timeFormatter);

String title = "🗓️ " + nickname + "님! " + plan.getTitle() + " 시간이에요! ";
String body = startTime + " - " + endTime + " \n" +
(plan.getDescription() != null ? plan.getDescription() : " ");

Notification notification = new Notification(title, body);

Message message = Message.builder()
.setToken(fcmToken.getToken())
.setNotification(notification)
.putData("title", plan.getTitle())
.putData("title", plan.getDescription())
.putData("startDate", plan.getStartDate().toString())
.build();
Message message = Message.builder().setToken(fcmToken.getToken()).setNotification(notification).putData("title", plan.getTitle()).putData("title", plan.getDescription()).putData("startDate", plan.getStartDate().toString()).build();
try {
String response = firebaseMessaging.send(message);
log.info("알림을 정상적으로 전송하였습니다. : {}", response);

// 알림 전송 기록 저장
NotificationLog logEntry = NotificationLog.builder()
.fcmToken(fcmToken)
.plan(plan)
.sentAt(LocalDateTime.now())
.build();
NotificationLog logEntry = NotificationLog.builder().fcmToken(fcmToken).plan(plan).sentAt(LocalDateTime.now()).build();
notificationLogRepository.save(logEntry);

} catch (Exception e) {
log.error("FCM 알림 전송 실패 ", e);
}
}

// 알림 테스트를 위한 메소드 (추후 삭제)
public void sendTestNotification(Long userId) {
List<FcmToken> fcmTokens = fcmTokenRepository.findByUserId(userId);

for (FcmToken fcmToken : fcmTokens) {
Notification notification = new Notification("테스트 알림", "이것은 테스트 알림입니다.");

Message message = Message.builder()
.setToken(fcmToken.getToken())
.setNotification(notification)
.build();

try {
String response = firebaseMessaging.send(message);
log.info("Successfully sent message: {}", response);
} catch (Exception e) {
log.error("Failed to send FCM notification", e);
}
}
}
}
5 changes: 5 additions & 0 deletions src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ spring:
registration:
kakao:
redirect-uri: http://localhost:8080/login/oauth2/code/kakao

logging:
level:
org.springframework.security: TRACE
org.hibernate.engine.internal.StatisticalLoggingSessionEventListener: OFF
5 changes: 5 additions & 0 deletions src/main/resources/application-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ spring:
registration:
kakao:
redirect-uri: https://api.splanet.co.kr/login/oauth2/code/kakao

logging:
level:
org.springframework.security: INFO
org.hibernate.engine.internal.StatisticalLoggingSessionEventListener: OFF
6 changes: 0 additions & 6 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ spring:
scope: profile_nickname, profile_image, account_email
client-name: Kakao

logging:
level:
org.springframework.security: TRACE
org.hibernate.engine.internal.StatisticalLoggingSessionEventListener: OFF


springdoc:
swagger-ui:
path: /swagger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,44 +87,4 @@ void setUp() {
e.printStackTrace();
}
}

@Test
void 테스트_알림_전송_성공() {
Long userId = 1L;
FcmToken fcmToken = FcmToken.builder()
.token("FCM토큰")
.build();

when(fcmTokenRepository.findByUserId(userId)).thenReturn(List.of(fcmToken));
try {
when(firebaseMessaging.send(any(Message.class))).thenReturn("응답");

assertDoesNotThrow(() -> notificationService.sendTestNotification(userId));
verify(firebaseMessaging, times(1)).send(any(Message.class));
verify(fcmTokenRepository, times(1)).findByUserId(userId);

} catch (Exception e) {
e.printStackTrace();
}
}

@Test
void 테스트_알림_전송_실패() {
Long userId = 1L;
FcmToken fcmToken = FcmToken.builder()
.token("FCM토큰")
.build();

when(fcmTokenRepository.findByUserId(userId)).thenReturn(Collections.singletonList(fcmToken));
try {
when(firebaseMessaging.send(any(Message.class))).thenThrow(new RuntimeException("FCM 전송 실패"));

assertDoesNotThrow(() -> notificationService.sendTestNotification(userId));
verify(firebaseMessaging, times(1)).send(any(Message.class));
verify(fcmTokenRepository, times(1)).findByUserId(userId);

} catch (Exception e) {
e.printStackTrace();
}
}
}

0 comments on commit 791671b

Please sign in to comment.