Skip to content

Commit

Permalink
Merge pull request #25 from hyundai-fruitfruit/HEENDY-88-push-res
Browse files Browse the repository at this point in the history
[Heendy 88 push res] FCM 푸시 알림 전송 방식 변경 및 시연용 api 추가
  • Loading branch information
sooyoungh authored Mar 3, 2024
2 parents e08e2e5 + 4836664 commit e5c07d3
Show file tree
Hide file tree
Showing 16 changed files with 207 additions and 34 deletions.
5 changes: 3 additions & 2 deletions src/main/java/com/hyundai/app/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public void configure(WebSecurity web) {
web.ignoring().antMatchers(
"/", "/resources/**",
"/v2/api-docs", "/swagger-resources/**", "/swagger-ui/index.html", "/swagger-ui.html","/webjars/**", "/swagger/**", // swagger
"/api/v1/auth/**", "/api/v1/admin/**", "/api/v1/fcm-push/**", "/api/v1/heendy-guide/**", "/websocket/**");
"/api/v1/auth/**", "/api/v1/admin/**", "/api/v1/fcm-push/random-spot/**", "/api/v1/heendy-guide/**", "/websocket/**");
}

@Override
Expand All @@ -62,7 +62,8 @@ public void configure(HttpSecurity httpSecurity) throws Exception {
.authorizeRequests()
.antMatchers("/api/v1/auth/**").permitAll()
.antMatchers("/api/v1/admin/**").permitAll()
.antMatchers("/api/v1/fcm/**").permitAll()
.antMatchers("/api/v1/fcm-push/**").permitAll()
.antMatchers("/api/v1/fcm-push/**").permitAll()
.antMatchers("/api/v1/stores/**").authenticated()
.antMatchers("/api/v1/members/**").authenticated()
.anyRequest().permitAll()
Expand Down
46 changes: 33 additions & 13 deletions src/main/java/com/hyundai/app/fcm/FcmController.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.hyundai.app.fcm;

import com.hyundai.app.fcm.dto.PushReqDto;
import com.hyundai.app.security.methodparam.MemberId;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.time.LocalDateTime;
import java.util.concurrent.ExecutionException;
Expand All @@ -18,26 +20,14 @@
* FCM 테스트용 컨트롤러
*/
@Log4j
@Api("FCM 테스트용 API")
@Api("FCM 푸시 알림 API")
@RestController
@RequestMapping("/api/v1/fcm-push")
@RequiredArgsConstructor
public class FcmController {

private final FcmPushService fcmPushService;

/**
* @author 황수영
* @since 2024/02/20
* FCM 푸시 알림 테스트용 - 바로 FCM 알림 발송
*/
@ApiOperation("FCM 테스트용 API")
@PostMapping("/test/{deviceToken}")
public ResponseEntity<Void> testPush(@PathVariable String deviceToken) throws ExecutionException, InterruptedException {
fcmPushService.testPush(deviceToken);
return new ResponseEntity<>(HttpStatus.OK);
}

/**
* @author 황수영
* @since 2024/02/21
Expand All @@ -51,4 +41,34 @@ public ResponseEntity<Void> pushRandomSpot(@RequestBody PushReqDto pushReqDto) {
fcmPushService.createRandomSpotPushSchedule(pushReqDto);
return new ResponseEntity<>(HttpStatus.OK);
}

/**
* @author 황수영
* @since 2024/02/20
* FCM 푸시 알림 테스트용 - 디바이스 토큰만
*/
@ApiOperation("FCM 테스트용 API : 디바이스 토큰으로 푸시알림 발송")
@PostMapping("/random-spot/device-token")
public ResponseEntity<Void> pushByDeviceToken(
@RequestBody PushReqDto pushReqDto) throws ExecutionException, InterruptedException
{
log.debug("랜덤 스팟 FCM 푸시 알림 바로 전송 => device token : " + pushReqDto.getDeviceToken());
fcmPushService.testPush(pushReqDto.getDeviceToken());
return new ResponseEntity<>(HttpStatus.OK);
}

/**
* @author 황수영
* @since 2024/02/20
* FCM 푸시 알림 시연용 - 로그인한 유저에게 바로 FCM 알림 발송
*/
@ApiOperation("FCM 시연용 API : 호출 시, 로그인한 유저에게 푸시알림 발송")
@GetMapping
public ResponseEntity<Void> pushByMemberId(
@ApiIgnore @MemberId String memberId
) throws ExecutionException, InterruptedException {
log.debug("랜덤 스팟 FCM 푸시 알림 바로 전송 => memberId : " + memberId);
fcmPushService.createRandomSpotPushByMemberId(memberId);
return new ResponseEntity<>(HttpStatus.OK);
}
}
41 changes: 40 additions & 1 deletion src/main/java/com/hyundai/app/fcm/FcmPushService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

import com.google.firebase.FirebaseApp;
import com.google.firebase.messaging.FirebaseMessaging;
import com.hyundai.app.exception.AdventureOfHeendyException;
import com.hyundai.app.exception.ErrorCode;
import com.hyundai.app.fcm.dto.PushMessageDto;
import com.hyundai.app.fcm.dto.PushReqDto;
import com.hyundai.app.member.domain.Member;
import com.hyundai.app.member.mapper.MemberMapper;
import com.hyundai.app.scheduler.PushScheduler;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j;
Expand All @@ -26,6 +31,12 @@ public class FcmPushService {
private FirebaseApp firebaseApp;
@Autowired
private PushScheduler pushScheduler;
@Autowired
private MemberMapper memberMapper;

@Autowired
private PushAlarmMapper pushAlarmMapper;


/**
* @author 황수영
Expand All @@ -34,7 +45,7 @@ public class FcmPushService {
*/
public void testPush(String deviceToken) throws ExecutionException, InterruptedException {
log.debug("알림 테스트 시작");
Notification notification = PushType.createNotification(PushType.WELCOME);
Notification notification = PushType.createNotification(createPushMessage(PushType.RANDOM_SPOT.getId()));
Message message = PushType.createMessage(notification, deviceToken);
FirebaseMessaging.getInstance(firebaseApp).sendAsync(message).get();
}
Expand All @@ -48,4 +59,32 @@ public void createRandomSpotPushSchedule(PushReqDto pushReqDto) {
log.debug("createRandomSpotPushSchedule => 랜덤 스팟 푸시 알림");
pushScheduler.schedulePushForRandomSpot(pushReqDto);
}

/**
* @author 황수영
* @since 2024/02/20
* 랜덤 스팟 FCM 푸시 알림 전송
*/
public void createRandomSpotPushByMemberId(String memberId) throws ExecutionException, InterruptedException{
log.debug("createRandomSpotPushSchedule => 랜덤 스팟 푸시 알림");
Notification notification = PushType.createNotification(createPushMessage(PushType.RANDOM_SPOT.getId()));

Member member = memberMapper.findById(memberId);
if (member == null) {
log.debug("존재하는 회원 없습니다. memberId : " + memberId);
throw new AdventureOfHeendyException(ErrorCode.MEMBER_NOT_EXIST);
}
Message message = PushType.createMessage(notification, member.getDeviceToken());
FirebaseMessaging.getInstance(firebaseApp).sendAsync(message).get();
}

/**
* @author 황수영
* @since 2024/03/01
* 랜덤 스팟 FCM 푸시 알림 메시지 생성용
*/
public PushMessageDto createPushMessage(int id){
PushAlarm pushAlarm = pushAlarmMapper.getPushAlarmById(id);
return PushMessageDto.of(pushAlarm.getTitle(), pushAlarm.getContent(), pushAlarm.getImage());
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/hyundai/app/fcm/PushAlarm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.hyundai.app.fcm;

import lombok.*;

/**
* @author 황수영
* @since 2024/03/02
* 푸시 알림 도메인 (이벤트별로 메시지 설정용)
*/
@Getter
@Builder
@ToString
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PushAlarm {
private String title;
private String content;
private String image;
}
10 changes: 10 additions & 0 deletions src/main/java/com/hyundai/app/fcm/PushAlarmMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.hyundai.app.fcm;

/**
* @author 황수영
* @since 2024/03/02
* 푸시 알림 매퍼
*/
public interface PushAlarmMapper {
PushAlarm getPushAlarmById(int id);
}
13 changes: 7 additions & 6 deletions src/main/java/com/hyundai/app/fcm/PushType.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
@Getter
@AllArgsConstructor
public enum PushType {
RANDOM_SPOT("흰디의 모험에 온 걸 환영해🎉",
"나는 대장 흰디야! 반가워",
"https://avatars.githubusercontent.com/u/158237286?s=400&u=db03152b8b64ca04183e918814f02316a5e8c4d9&v=4"),
WELCOME("'흰디의 모험' 랜덤 스팟이 열렸어🎁",
WELCOME(1, "'흰디의 모험' 랜덤 스팟이 열렸어🎁",
"랜덤 스팟에서의 이벤트를 확인해봐",
"https://avatars.githubusercontent.com/u/158237286?s=400&u=db03152b8b64ca04183e918814f02316a5e8c4d9&v=4"),
RANDOM_SPOT(2, "흰디의 모험에 온 걸 환영해🎉",
"나는 대장 흰디야! 반가워",
"https://avatars.githubusercontent.com/u/158237286?s=400&u=db03152b8b64ca04183e918814f02316a5e8c4d9&v=4");


private final int id;
private final String title;
private final String content;
private final String image;
Expand All @@ -30,8 +32,7 @@ public enum PushType {
* @since 2024/02/20
* Notification 생성
*/
public static Notification createNotification(PushType pushType) {
PushMessageDto pushMessageDto = PushMessageDto.of(pushType);
public static Notification createNotification(PushMessageDto pushMessageDto) {

return Notification.builder()
.setTitle(pushMessageDto.getTitle())
Expand Down
14 changes: 8 additions & 6 deletions src/main/java/com/hyundai/app/fcm/dto/PushMessageDto.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.hyundai.app.fcm.dto;

import com.hyundai.app.fcm.PushType;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
Expand All @@ -10,16 +11,17 @@
*/

@Getter
@AllArgsConstructor
public class PushMessageDto {
private String title;
private String content;
private String image;

public static PushMessageDto of(PushType pushType) {
PushMessageDto pushMessageDto = new PushMessageDto();
pushMessageDto.content = pushType.getContent();
pushMessageDto.title = pushType.getTitle();
pushMessageDto.image = pushType.getImage();
return pushMessageDto;
public static PushMessageDto from(PushType pushType) {
return new PushMessageDto(pushType.getTitle(), pushType.getContent(), pushType.getImage());
}

public static PushMessageDto of(String title, String content, String image) {
return new PushMessageDto(title, content, image);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.hyundai.app.member.controller;

import com.hyundai.app.common.AdventureOfHeendyResponse;
import com.hyundai.app.member.dto.DeviceTokenDto;
import com.hyundai.app.member.dto.MemberResDto;
import com.hyundai.app.member.service.MemberService;
import com.hyundai.app.security.methodparam.MemberId;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
Expand All @@ -22,7 +22,6 @@
*/
@Log4j
@Api("회원 관련 API")
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/members")
public class MemberController {
Expand All @@ -44,6 +43,22 @@ public ResponseEntity<MemberResDto> login(@ApiIgnore @MemberId String memberId)
return new ResponseEntity<>(memberResDto, HttpStatus.ACCEPTED);
}

/**
* @author 황수영
* @since 2024/02/14
* FCM 디바이스 토큰 업데이트
*/
@PostMapping("/token")
@ApiOperation("FCM 디바이스 토큰 업데이트 API")
public ResponseEntity<Void> updateDeviceToken(
@ApiIgnore @MemberId String memberId,
@RequestBody DeviceTokenDto deviceTokenDto
) {
log.debug("FCM 디바이스 토큰 업데이트 : " + memberId + " token : " + deviceTokenDto.getToken());
memberService.updateDeviceToken(memberId, deviceTokenDto);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}

/**
* @author 엄상은
* @since 2024/02/26
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/hyundai/app/member/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class Member extends BaseEntity {
private String nickname;
private Role role;
private String refreshToken;
private String deviceToken;
private String oauthId;
private String imgUrl;
private String qrUrl;
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/hyundai/app/member/dto/DeviceTokenDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.hyundai.app.member.dto;

import lombok.Getter;

/**
* @author 황수영
* @since 2024/03/02
* FCM 디바이스 토큰 값 업데이트
*/
@Getter
public class DeviceTokenDto {
private String platform; // FCM
private String token;
}
2 changes: 2 additions & 0 deletions src/main/java/com/hyundai/app/member/mapper/MemberMapper.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.hyundai.app.member.mapper;

import com.hyundai.app.member.domain.Member;
import org.apache.ibatis.annotations.Param;

/**
* @author 황수영
Expand All @@ -13,4 +14,5 @@ public interface MemberMapper {
Member findById(String id);
Member findByOauthId(String oauthId);
void updateQrUrl(Member member);
void updateDeviceToken(@Param("id") String id, @Param("token")String token);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.hyundai.app.member.service;

import com.hyundai.app.member.dto.DeviceTokenDto;
import com.hyundai.app.member.dto.LoginReqDto;
import com.hyundai.app.member.dto.LoginResDto;
import com.hyundai.app.member.dto.MemberResDto;
Expand All @@ -13,6 +14,7 @@
public interface MemberService {

MemberResDto getMemberInfo(String id);
void updateDeviceToken(String memberId, DeviceTokenDto deviceTokenDto);

LoginResDto login(LoginReqDto loginReqDto);

Expand Down
Loading

0 comments on commit e5c07d3

Please sign in to comment.