Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Heendy 88 push res] FCM 푸시 알림 전송 방식 변경 및 시연용 api 추가 #25

Merged
merged 4 commits into from
Mar 3, 2024
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
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
Loading