diff --git a/README.md b/README.md index 4589a677..db2ff49f 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,119 @@ -# KnockKnock-Backend - -디프만 12기 칠면조 KnockKnock Backend입니다. - -# KnockKnock 프로젝트를 시작하기전 - -## 목차 - -* [개발 프로세스](https://github.com/TEAM-XQUARE/README.md#개발-프로세스) -* [이슈규칙](https://github.com/TEAM-XQUARE/README.md#이슈-규칙) -* [커밋규칙](https://github.com/TEAM-XQUARE/README.md#커밋-규칙) -* [브랜치규칙](https://github.com/TEAM-XQUARE/README.md#브랜치-규칙) -* [버전규칙](https://github.com/TEAM-XQUARE/README.md#버전-규칙) -* [Lisence](https://github.com/team-xquare/README.md/blob/main/README.md#license) - - +

+

푸시알림 커스텀 서비스, Knocknock

+

+ +

+ +--- + +![Group 48095933](https://user-images.githubusercontent.com/13329304/212319564-fb9dc5ec-31e9-4e47-8034-cd5148cddb6b.png) + +--- + +### :computer: 개발자 선생님들 :computer: + + + + + + + + + + + + + + + + + +
백엔드, 팀장백엔드백엔드
이서준이찬진배정은
+ +
+ leeseojune53 +
+ +
+ ImNM +
+ +
+ mybloom +
+ + + + + + + + + + + + + + + + + + + + +
AOS 팀장AOSAOSAOS
황규일이영준조준장최현정
+ +
+ Gyuil-Hwnag +
+ +
+ leeyjwinter +
+ +
+ junjange +
+ +
+ hyunjung-choi +
+ +### :art: 하늘같은 디자인 선생님들 :art: + + + + + + + + + + + + + + + + + +
디자인디자인디자인
김나영박수연진승희
+ +
+ 김나영 +
+ +
+ 박수연 +
+ +
+ 진승희 +
+ +--- + +# KnockKnock 백엔드 팀의 규칙 ## 개발 프로세스 @@ -28,69 +128,34 @@ > 6. merge 후 feature branch 제거 > 7. issue close - - -## 이슈 규칙 - -> 한 기능 당 하나의 issue 생성을 원칙으로 합니다. -> -> 생성한 issue 성격이 맞는 label을 선택하여 추가한다. - -``` [Domain] Subject - - Subject - -``` - -위는 모든 이슈 메세지의 형식이다. - -### Labels - -> 새 리포지토리를 생성하면 issue label을 위같이 설정한다. - -| Label | Description | Color Code | 의미 | -| ------------- | ------------------------------------------ | ---------- | ------------------------------------------------------------ | -| 버그 | Something isn't working | #d73a4a | 예기치 않은 문제 또는 의도하지 않은 동작(버그)을 나타냅니다. | -| 기능 추가 | New feature or request | #a2eeef | 새로운 기능 요청을 나타냅니다. | -| DOCS | Improvements or additions to documentation | #cfd3d7 | 문서를 개선하거나 추가 할 필요가 있음을 나타냅니다. | -| Chore | | #0075ca | 자잘한 수정들을 나타냅니다. | -| 리펙토링 | Refactoring is needed | #008672 | 리펙토링이 필요함을 나타냅니다. | -| 프로젝트 설정 | Project setting is needed | #555303 | 프로젝트 설정이 필요함을 나타냅니다. | -| 테스트 추가 | Request a new test | #CD7F57 | 새로운 테스트 요청을 나타냅니다. | - - - ## 커밋 규칙 -> 프론트엔드라면 아래 링크를 확인해주세요! -* [프론트엔드](https://github.com/team-xquare/README.md/tree/main/frontend) ### 커밋메세지 > 다음은 커밋메세지의 형식입니다. -``` - CommitType :: (#issue number) Subject - ``` -### Commit Type - - > 다음은 커밋타입 형식입니다. + CommitType :: (#issue number) Subject -|CommitType|설명| -|------|----------------------| -|📑 ::|파일 생성 및 구조 변경| -|⚡️ ::|기능 업데이트| -|⚰️ ::|기능 삭제| -|🐛 ::|버그 수정| -|♻️ ::|코드 리펙토링| -|📝 ::|문서 작성 및 수정| -|⚙️ ::|프로젝트 세팅| -|🧪 ::|테스트 코드 추가| -|🚀 ::|새 버전 릴리즈 ( 커밋은 아니지만😏| -|🔀 ::|Merge or PR| +``` +### Commit Type +> 다음은 커밋타입 형식입니다. + +| CommitType | 설명 | +| ---------- | ---------------------------------- | +| 📑 :: | 파일 생성 및 구조 변경 | +| ⚡️ :: | 기능 업데이트 | +| ⚰️ :: | 기능 삭제 | +| 🐛 :: | 버그 수정 | +| ♻️ :: | 코드 리펙토링 | +| 📝 :: | 문서 작성 및 수정 | +| ⚙️ :: | 프로젝트 세팅 | +| 🧪 :: | 테스트 코드 추가 | +| 🚀 :: | 새 버전 릴리즈 ( 커밋은 아니지만😏 | +| 🔀 :: | Merge or PR | ### issue number @@ -108,9 +173,9 @@ > 커밋메세지 형식의 Subject 부분에 기재 -* 50자를 넘기지 않게 명령형으로 작성한다. -* 한국어로 작성한다. -* ```어떻게``` 보단 ```무엇을```, ```왜``` 에 초점을 두고 작성한다. +- 50자를 넘기지 않게 명령형으로 작성한다. +- 한국어로 작성한다. +- `어떻게` 보단 `무엇을`, `왜` 에 초점을 두고 작성한다. ```bash @@ -125,18 +190,19 @@ ``` 🐛 :: [MainPage] 헤더가 안보이는 버그 수정 ``` + ``` 🐛 :: (#19)[FeedServiceImpl] 피드 버그 로직 수정 ``` + ``` 🚀 :: v1.0.0 ``` + ``` 📝 :: README 파일 수정 ``` - - ### 브랜치 규칙 > 기본적으로 GitFlow를 따릅니다 @@ -144,45 +210,5 @@ ### Feature Branch ```markdown - -Feature/{issue number}_{todo} - -``` - - - -### 버전 규칙 - -![버전 규칙](https://user-images.githubusercontent.com/67373938/119933978-0ac15300-bfc0-11eb-99cd-0198b1ee6f2d.png) - -> 모든 버전은 01.00.00에서 시작한다. - -```jsx - -"01.01.09" 생략시 "1.1.9" - -"01.01.10" 생략시 "1.1.10" - +Feature/{issue number}\_{todo} ``` - -### Major Version - -- 1로 시작한다. -- 증가 시 나머지 버전 정보 초기화 -- 전체를 뒤엎었을때 변화한다. - -### Minor Version - -- 00으로 시작한다 -- 없던 기능의 추가나 기존 기능의 수정 등의 변화가 발생했을때 이 수치를 올린다. - -### Patches - -+ 00으로 시작한다. - -- 자잘한 버그나 내부적 코드 보완 등의 변화가 발생했을때 이 수치를 올린다. - - -## License -> 해당 문서에 대한 라이센스는 대덕소프트웨어 마이스터 고등학교의 SEMICOLON; & XQUARE팀에 있습니다. -> 해당 문서는 출처만 남겨주신다면, 자유롭게 이용하실 수 있습니다! diff --git a/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/FcmResponseException.java b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/FcmServerException.java similarity index 52% rename from src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/FcmResponseException.java rename to src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/FcmServerException.java index b2d78007..d574525a 100644 --- a/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/FcmResponseException.java +++ b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/FcmServerException.java @@ -4,10 +4,10 @@ import io.github.depromeet.knockknockbackend.global.error.exception.ErrorCode; import io.github.depromeet.knockknockbackend.global.error.exception.KnockException; -public class FcmResponseException extends KnockException { - public static final KnockException EXCEPTION = new FcmResponseException(); +public class FcmServerException extends KnockException { + public static final KnockException EXCEPTION = new FcmServerException(); - private FcmResponseException() { - super(ErrorCode.NOTIFICATION_FCM_FAIL_SEND); + private FcmServerException() { + super(ErrorCode.NOTIFICATION_FCM_SERVER_ERROR); } } diff --git a/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/FcmTokenInvalidException.java b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/FcmTokenInvalidException.java new file mode 100644 index 00000000..f3ce8e3a --- /dev/null +++ b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/FcmTokenInvalidException.java @@ -0,0 +1,13 @@ +package io.github.depromeet.knockknockbackend.domain.notification.exception; + + +import io.github.depromeet.knockknockbackend.global.error.exception.ErrorCode; +import io.github.depromeet.knockknockbackend.global.error.exception.KnockException; + +public class FcmTokenInvalidException extends KnockException { + public static final KnockException EXCEPTION = new FcmTokenInvalidException(); + + private FcmTokenInvalidException() { + super(ErrorCode.NOTIFICATION_FCM_TOKEN_INVALID); + } +} diff --git a/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/NotificationInvalidFcmToken.java b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/NotificationInvalidFcmToken.java new file mode 100644 index 00000000..b3857ef1 --- /dev/null +++ b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/exception/NotificationInvalidFcmToken.java @@ -0,0 +1,13 @@ +package io.github.depromeet.knockknockbackend.domain.notification.exception; + + +import io.github.depromeet.knockknockbackend.global.error.exception.ErrorCode; +import io.github.depromeet.knockknockbackend.global.error.exception.KnockException; + +public class NotificationInvalidFcmToken extends KnockException { + public static final KnockException EXCEPTION = new NotificationInvalidFcmToken(); + + private NotificationInvalidFcmToken() { + super(ErrorCode.NOTIFICATION_FCM_TOKEN_INVALID); + } +} diff --git a/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationService.java b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationService.java index 8da985b7..2bde6b3d 100644 --- a/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationService.java +++ b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationService.java @@ -10,7 +10,6 @@ import io.github.depromeet.knockknockbackend.domain.notification.domain.*; import io.github.depromeet.knockknockbackend.domain.notification.domain.Notification; import io.github.depromeet.knockknockbackend.domain.notification.domain.repository.DeviceTokenRepository; -import io.github.depromeet.knockknockbackend.domain.notification.domain.repository.NotificationExperienceRepository; import io.github.depromeet.knockknockbackend.domain.notification.domain.repository.NotificationRepository; import io.github.depromeet.knockknockbackend.domain.notification.domain.repository.ReservationRepository; import io.github.depromeet.knockknockbackend.domain.notification.domain.vo.NotificationReactionCountInfoVo; @@ -47,7 +46,6 @@ public class NotificationService { private final DeviceTokenRepository deviceTokenRepository; private final NotificationReactionRepository notificationReactionRepository; private final ReservationRepository reservationRepository; - private final NotificationExperienceRepository notificationExperienceRepository; private final GroupUserRepository groupUserRepository; @Transactional(readOnly = true) @@ -186,9 +184,7 @@ public void sendInstance(SendInstanceRequest request) { } public void sendInstanceToMeBeforeSignUp(SendInstanceToMeBeforeSignUpRequest request) { - fcmService.sendMessage(request.getToken(), request.getContent()); - notificationExperienceRepository.save( - NotificationExperience.of(request.getToken(), request.getContent())); + notificationUtils.sendExperienceNotification(request.getToken(), request.getContent()); } public void deleteByNotificationId(Long notificationId) { diff --git a/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationUtils.java b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationUtils.java index cdd6d668..e4d7a04e 100644 --- a/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationUtils.java +++ b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationUtils.java @@ -14,4 +14,6 @@ void sendNotification( String content, String imageUrl, LocalDateTime reservedAt); + + void sendExperienceNotification(String token, String content); } diff --git a/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationUtilsImpl.java b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationUtilsImpl.java index 586f5721..3ed52e18 100644 --- a/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationUtilsImpl.java +++ b/src/main/java/io/github/depromeet/knockknockbackend/domain/notification/service/NotificationUtilsImpl.java @@ -1,26 +1,44 @@ package io.github.depromeet.knockknockbackend.domain.notification.service; +import com.google.api.core.ApiFuture; +import com.google.firebase.ErrorCode; +import com.google.firebase.messaging.BatchResponse; +import com.google.firebase.messaging.FirebaseMessagingException; +import com.google.firebase.messaging.MessagingErrorCode; +import com.google.firebase.messaging.SendResponse; import io.github.depromeet.knockknockbackend.domain.group.domain.Group; import io.github.depromeet.knockknockbackend.domain.notification.domain.DeviceToken; import io.github.depromeet.knockknockbackend.domain.notification.domain.NightCondition; import io.github.depromeet.knockknockbackend.domain.notification.domain.Notification; +import io.github.depromeet.knockknockbackend.domain.notification.domain.NotificationExperience; +import io.github.depromeet.knockknockbackend.domain.notification.domain.repository.DeviceTokenRepository; +import io.github.depromeet.knockknockbackend.domain.notification.domain.repository.NotificationExperienceRepository; import io.github.depromeet.knockknockbackend.domain.notification.domain.repository.NotificationRepository; +import io.github.depromeet.knockknockbackend.domain.notification.exception.FcmServerException; +import io.github.depromeet.knockknockbackend.domain.notification.exception.FcmTokenInvalidException; import io.github.depromeet.knockknockbackend.domain.notification.exception.NotificationNotFoundException; import io.github.depromeet.knockknockbackend.domain.user.domain.User; import io.github.depromeet.knockknockbackend.infrastructor.fcm.FcmService; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; +import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; +import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +@Slf4j @RequiredArgsConstructor @Component public class NotificationUtilsImpl implements NotificationUtils { private final FcmService fcmService; private final NotificationRepository notificationRepository; + private final DeviceTokenRepository deviceTokenRepository; + private final NotificationExperienceRepository notificationExperienceRepository; @Override public Notification queryNotificationById(Long notificationId) { @@ -53,7 +71,28 @@ public void sendNotification( if (tokens.isEmpty()) { return; } - fcmService.sendGroupMessage(tokens, title, content, imageUrl); + ApiFuture batchResponseApiFuture = + fcmService.sendGroupMessageAsync(tokens, title, content, imageUrl); + checkFcmResponse(deviceTokens, tokens, batchResponseApiFuture); + } + + @Override + public void sendExperienceNotification(String token, String content) { + try { + fcmService.sendMessageSync(token, content); + } catch (FirebaseMessagingException e) { + ErrorCode errorCode = e.getErrorCode(); + log.error( + "**[sendMessageSync] errorCode: {}, errorMessage: {}", + errorCode, + e.getMessage()); + if (errorCode.equals(ErrorCode.INVALID_ARGUMENT)) { + throw FcmTokenInvalidException.EXCEPTION; + } + throw FcmServerException.EXCEPTION; + } + + notificationExperienceRepository.save(NotificationExperience.of(token, content)); } private List getDeviceTokens(Long groupId, Long sendUserId) { @@ -83,4 +122,53 @@ private void recordNotification( deviceTokens, title, content, imageUrl, group, sendUser, reservedAt); notificationRepository.save(notification); } + + private void checkFcmResponse( + List deviceTokens, + List tokens, + ApiFuture batchResponseApiFuture) { + try { + List responses = batchResponseApiFuture.get().getResponses(); + IntStream.iterate(0, i -> i + 1) + .limit(responses.size()) + .filter(i -> responses.get(i).getException() != null) + .filter( + i -> + responses + .get(i) + .getException() + .getMessagingErrorCode() + .equals(MessagingErrorCode.INVALID_ARGUMENT)) + .forEach( + i -> { + String errorToken = tokens.get(i); + String errorMessage = responses.get(i).getException().getMessage(); + MessagingErrorCode errorCode = + responses.get(i).getException().getMessagingErrorCode(); + + Optional errorDeviceToken = + deviceTokens.stream() + .filter( + deviceToken -> + deviceToken + .getToken() + .equals(errorToken)) + .findAny(); + Long IdOfErrorDeviceToken = + errorDeviceToken.map(DeviceToken::getId).orElse(null); + Long userIdOfErrorDeviceToken = + errorDeviceToken.map(DeviceToken::getUserId).orElse(null); + deviceTokenRepository.deleteById(IdOfErrorDeviceToken); + + log.error( + "**[sendGroupMessageAsync] errorUserId: {}, errorMessage: {}, errorCode: {}, errorToken: {}", + userIdOfErrorDeviceToken, + errorMessage, + errorCode, + errorToken); + }); + } catch (InterruptedException | ExecutionException e) { + throw FcmTokenInvalidException.EXCEPTION; + } + } } diff --git a/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/domain/NotificationReaction.java b/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/domain/NotificationReaction.java index 815f7b0d..10d2ac97 100644 --- a/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/domain/NotificationReaction.java +++ b/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/domain/NotificationReaction.java @@ -46,6 +46,14 @@ public class NotificationReaction extends BaseTimeEntity { @ManyToOne(fetch = FetchType.LAZY) private User user; + public Long getUserId() { + return user.getId(); + } + + public void changeReaction(Reaction reaction) { + this.reaction = reaction; + } + public static NotificationReaction of(Long id, Reaction reaction) { return NotificationReaction.builder().id(id).reaction(reaction).build(); } diff --git a/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/exception/ReactionNotExistException.java b/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/exception/ReactionNotExistException.java new file mode 100644 index 00000000..b93ecddd --- /dev/null +++ b/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/exception/ReactionNotExistException.java @@ -0,0 +1,13 @@ +package io.github.depromeet.knockknockbackend.domain.reaction.exception; + + +import io.github.depromeet.knockknockbackend.global.error.exception.ErrorCode; +import io.github.depromeet.knockknockbackend.global.error.exception.KnockException; + +public class ReactionNotExistException extends KnockException { + public static final KnockException EXCEPTION = new ReactionNotExistException(); + + private ReactionNotExistException() { + super(ErrorCode.REACTION_NOT_EXIST); + } +} diff --git a/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/service/ReactionService.java b/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/service/ReactionService.java index 7f83ea10..9c72edca 100644 --- a/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/service/ReactionService.java +++ b/src/main/java/io/github/depromeet/knockknockbackend/domain/reaction/service/ReactionService.java @@ -7,6 +7,7 @@ import io.github.depromeet.knockknockbackend.domain.reaction.domain.repository.NotificationReactionRepository; import io.github.depromeet.knockknockbackend.domain.reaction.exception.ReactionAlreadyExistException; import io.github.depromeet.knockknockbackend.domain.reaction.exception.ReactionForbiddenException; +import io.github.depromeet.knockknockbackend.domain.reaction.exception.ReactionNotExistException; import io.github.depromeet.knockknockbackend.domain.reaction.presentation.dto.request.RegisterReactionRequest; import io.github.depromeet.knockknockbackend.global.utils.security.SecurityUtils; import io.github.depromeet.knockknockbackend.global.utils.user.UserUtils; @@ -34,30 +35,32 @@ public void registerReaction(RegisterReactionRequest request) { } } + @Transactional public void changeReaction(Long notificationReactionId, RegisterReactionRequest request) { - validateMyReactionTheNotification(notificationReactionId); + NotificationReaction notificationReaction = + queryNotificationReaction(notificationReactionId); + validateMyReactionTheNotification(notificationReaction); - notificationReactionRepository.save( - NotificationReaction.of( - notificationReactionId, Reaction.of(request.getReactionId()))); + notificationReaction.changeReaction(Reaction.of(request.getReactionId())); } @Transactional public void deleteReaction(Long notificationReactionId) { - validateMyReactionTheNotification(notificationReactionId); + NotificationReaction notificationReaction = + queryNotificationReaction(notificationReactionId); + validateMyReactionTheNotification(notificationReaction); notificationReactionRepository.deleteById(notificationReactionId); } - private void validateMyReactionTheNotification(Long notificationReactionId) { - notificationReactionRepository + private void validateMyReactionTheNotification(NotificationReaction notificationReaction) { + if (!notificationReaction.getUserId().equals(SecurityUtils.getCurrentUserId())) { + throw ReactionForbiddenException.EXCEPTION; + } + } + + private NotificationReaction queryNotificationReaction(Long notificationReactionId) { + return notificationReactionRepository .findById(notificationReactionId) - .ifPresent( - notificationReaction -> { - if (!notificationReaction - .getUser() - .getId() - .equals(SecurityUtils.getCurrentUserId())) - throw ReactionForbiddenException.EXCEPTION; - }); + .orElseThrow(() -> ReactionNotExistException.EXCEPTION); } } diff --git a/src/main/java/io/github/depromeet/knockknockbackend/domain/relation/domain/Relation.java b/src/main/java/io/github/depromeet/knockknockbackend/domain/relation/domain/Relation.java index d831f98e..346ad80b 100644 --- a/src/main/java/io/github/depromeet/knockknockbackend/domain/relation/domain/Relation.java +++ b/src/main/java/io/github/depromeet/knockknockbackend/domain/relation/domain/Relation.java @@ -5,19 +5,25 @@ import io.github.depromeet.knockknockbackend.domain.user.domain.vo.UserInfoVO; import javax.persistence.Entity; import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; @Getter +@NoArgsConstructor @Table(name = "tbl_relation") @Entity public class Relation { - @Id private Long id; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; private boolean isFriend; diff --git a/src/main/java/io/github/depromeet/knockknockbackend/global/error/exception/ErrorCode.java b/src/main/java/io/github/depromeet/knockknockbackend/global/error/exception/ErrorCode.java index e24d7277..96dc8c42 100644 --- a/src/main/java/io/github/depromeet/knockknockbackend/global/error/exception/ErrorCode.java +++ b/src/main/java/io/github/depromeet/knockknockbackend/global/error/exception/ErrorCode.java @@ -53,17 +53,23 @@ public enum ErrorCode { HttpStatus.BAD_REQUEST.value(), "REACTION-400-1", "reaction of the notification is already exist"), + REACTION_NOT_EXIST( + HttpStatus.BAD_REQUEST.value(), + "REACTION-400-2", + "reaction of the notification is not exist"), REACTION_FORBIDDEN( HttpStatus.FORBIDDEN.value(), "REACTION-403-1", "the user cannot change the reaction"), + NOTIFICATION_FCM_TOKEN_INVALID( + HttpStatus.BAD_REQUEST.value(), "NOTIFICATION-400-1", "FCM token invalid"), NOTIFICATION_FORBIDDEN( HttpStatus.FORBIDDEN.value(), "NOTIFICATION-403-1", "The user has no access to the notification"), NOTIFICATION_NOT_FOUND( HttpStatus.NOT_FOUND.value(), "NOTIFICATION-404-1", "Notification Not Found"), - NOTIFICATION_FCM_FAIL_SEND( - HttpStatus.INTERNAL_SERVER_ERROR.value(), "NOTIFICATION-500-1", "FCM ERROR"), + NOTIFICATION_FCM_SERVER_ERROR( + HttpStatus.INTERNAL_SERVER_ERROR.value(), "NOTIFICATION-500-1", "FCM server error"), RESERVATION_FORBIDDEN( HttpStatus.FORBIDDEN.value(), diff --git a/src/main/java/io/github/depromeet/knockknockbackend/infrastructor/fcm/FcmService.java b/src/main/java/io/github/depromeet/knockknockbackend/infrastructor/fcm/FcmService.java index ee6e097f..a5c37324 100644 --- a/src/main/java/io/github/depromeet/knockknockbackend/infrastructor/fcm/FcmService.java +++ b/src/main/java/io/github/depromeet/knockknockbackend/infrastructor/fcm/FcmService.java @@ -1,12 +1,8 @@ package io.github.depromeet.knockknockbackend.infrastructor.fcm; -import com.google.firebase.messaging.ApnsConfig; -import com.google.firebase.messaging.Aps; -import com.google.firebase.messaging.FirebaseMessaging; -import com.google.firebase.messaging.Message; -import com.google.firebase.messaging.MulticastMessage; -import com.google.firebase.messaging.Notification; +import com.google.api.core.ApiFuture; +import com.google.firebase.messaging.*; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -15,7 +11,7 @@ @Service public class FcmService { - public void sendGroupMessage( + public ApiFuture sendGroupMessageAsync( List tokenList, String title, String content, String imageUrl) { MulticastMessage multicast = MulticastMessage.builder() @@ -32,10 +28,10 @@ public void sendGroupMessage( .build()) .build(); - FirebaseMessaging.getInstance().sendMulticastAsync(multicast); + return FirebaseMessaging.getInstance().sendMulticastAsync(multicast); } - public void sendMessage(String token, String content) { + public void sendMessageSync(String token, String content) throws FirebaseMessagingException { Message message = Message.builder() .setToken(token) @@ -45,6 +41,7 @@ public void sendMessage(String token, String content) { .setAps(Aps.builder().setSound("default").build()) .build()) .build(); - FirebaseMessaging.getInstance().sendAsync(message); + + FirebaseMessaging.getInstance().send(message); } }