Skip to content

스케줄러와 FCM을 통한 목표 알림 기능 제작

Jemlog edited this page Nov 8, 2023 · 5 revisions

⚙️ 푸시 알림 기능 개발

✅ 구현 기능

스크린샷 2023-11-03 오후 2 18 13

마일스톤에는 사용자가 선택한 요일과 시간에 리마인드 알림을 보내주는 기능이 있습니다.

비즈니스 규칙

  • 요일은 복수 선택이 가능하다.
  • 시간 설정은 30분 단위로 가능하다. (ex. 7:00 -> 7:30 -> 8:00)
  • 사용자는 알림을 받을지 여부를 직접 선택 가능하다.

✅ 구현 시 고려사항

알림의 기준이 되는 목표 테이블과 요일을 저장하는 테이블

스크린샷 2023-11-08 오후 5 27 10

조회에 사용되는 컬럼

  • alarm_enabled : 알람을 보낼지 여부를 결정합니다.
  • alarm_time : 알람을 보내는 시간을 결정합니다.
  • detail_goal_alarm_days.alarm_days : 알람을 보내는 요일을 결정합니다.

✅ 코드 구현

알림을 전송해야 하는 목표 리스트를 조회하는 쿼리

public List<DetailGoalAlarmResponse> getMemberIdListDetailGoalAlarmTimeArrived(DayOfWeek dayOfWeek, LocalTime alarmTime)
{
    return query.select(detailGoal)
                .from(detailGoal)
                .where(
                        ...
                        detailGoal.alarmEnabled.isTrue(), // 알람을 허용한 하위 댓글 조회
                        detailGoal.alarmDays.contains(dayOfWeek), // 알람을 보내기로한 요일들에 현재 요일이 포함되는지 체크
                        detailGoal.alarmTime.between(alarmTime.minusMinutes(1),alarmTime.plusMinutes(1)) // 미세한 시간차를 고려해서 앞뒤로 1분까지 범위에 포함
                )
                .fetch();
    }

}

스케줄러 구현 코드

    @Scheduled(cron = "0 */30 * * * *", zone = "Asia/Seoul") // 30분 단위로 스케줄러가 동작합니다.
    public void sendAlarm()
    {
        DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); // 오늘이 어떤 요일인지 알아옵니다.
        LocalTime localTime = LocalTime.now(); // 현재 시간을 구합니다.
        LocalTime now = LocalTime.of(localTime.getHour(), localTime.getMinute(), 0);
         
        // 현재 요일과 시간에 해당하는 목표 리스트를 구해옵니다.
        List<DetailGoalAlarmResponse> detailGoalAlarmList = detailGoalQueryRepository.getMemberIdListDetailGoalAlarmTimeArrived(dayOfWeek, now);        

        // 조회한 목표의 사용자들에게 순차적으로 알림을 전송합니다.
        detailGoalAlarmList.forEach(alarmDto -> 
                        applicationEventPublisher.publishEvent(new AlarmEvent(alarmDto.uid(), alarmDto.detailGoalTitle())));
    }

DB에서 조회한 정보를 기반으로 유저들에게 FCM 푸시 알림을 전송합니다.