From 3198c4495086b1bed5c2e8cde0c997ad8af0ddf9 Mon Sep 17 00:00:00 2001 From: Jaehyeon Date: Wed, 22 Nov 2023 21:32:18 +0900 Subject: [PATCH] Feat: fcm --- .../article/service/ArticleService.java | 20 ++++- .../comment/service/CommentService.java | 19 +++++ .../friendship/service/FriendshipService.java | 14 +++- .../domain/like/service/LikeService.java | 38 +++++++-- .../fcm/service/FcmMessageProvider.java | 81 +------------------ 5 files changed, 79 insertions(+), 93 deletions(-) diff --git a/src/main/java/com/numberone/backend/domain/article/service/ArticleService.java b/src/main/java/com/numberone/backend/domain/article/service/ArticleService.java index 93f479a2..a32488e9 100644 --- a/src/main/java/com/numberone/backend/domain/article/service/ArticleService.java +++ b/src/main/java/com/numberone/backend/domain/article/service/ArticleService.java @@ -18,7 +18,9 @@ import com.numberone.backend.domain.like.repository.ArticleLikeRepository; import com.numberone.backend.domain.member.entity.Member; import com.numberone.backend.domain.member.repository.MemberRepository; +import com.numberone.backend.domain.notification.entity.NotificationEntity; import com.numberone.backend.domain.notification.entity.NotificationTag; +import com.numberone.backend.domain.notification.repository.NotificationRepository; import com.numberone.backend.domain.notificationregion.entity.NotificationRegion; import com.numberone.backend.domain.notificationregion.repository.NotificationRegionRepository; import com.numberone.backend.domain.token.util.SecurityContextProvider; @@ -42,8 +44,6 @@ import java.util.Objects; import java.util.Optional; -import static com.numberone.backend.support.notification.NotificationMessage.ARTICLE_COMMENT_FCM_ALARM; - @Slf4j @RequiredArgsConstructor @Transactional(readOnly = true) @@ -57,6 +57,7 @@ public class ArticleService { private final CommentRepository commentRepository; private final ArticleLikeRepository articleLikeRepository; private final NotificationRegionRepository notificationRegionRepository; + private final NotificationRepository notificationRepository; private final S3Provider s3Provider; private final LocationProvider locationProvider; private final FcmMessageProvider fcmMessageProvider; @@ -217,8 +218,19 @@ public CreateCommentResponse createComment(Long articleId, CreateCommentRequest .orElseThrow(NotFoundMemberException::new); articleParticipantRepository.save(new ArticleParticipant(article, member)); - // 게시글 작성자에게 알림을 보낸다. - fcmMessageProvider.sendFcm(articleOwner, ARTICLE_COMMENT_FCM_ALARM, NotificationTag.COMMUNITY); + + + String memberName = member.getNickName() != null ? member.getNickName() : member.getRealName(); + String title = String.format(""" + 나의 게시글에 %s님이 댓글을 달았어요. + """, memberName); + String body = "대피로에 접속하여 확인하세요!"; + + fcmMessageProvider.sendFcm(articleOwner, title, body, NotificationTag.COMMUNITY); + notificationRepository.save( + new NotificationEntity(articleOwner, NotificationTag.COMMUNITY, title, body, true) + ); + return CreateCommentResponse.of(savedComment); } diff --git a/src/main/java/com/numberone/backend/domain/comment/service/CommentService.java b/src/main/java/com/numberone/backend/domain/comment/service/CommentService.java index 825ab152..39917bfb 100644 --- a/src/main/java/com/numberone/backend/domain/comment/service/CommentService.java +++ b/src/main/java/com/numberone/backend/domain/comment/service/CommentService.java @@ -14,10 +14,14 @@ import com.numberone.backend.domain.like.repository.CommentLikeRepository; import com.numberone.backend.domain.member.entity.Member; import com.numberone.backend.domain.member.repository.MemberRepository; +import com.numberone.backend.domain.notification.entity.NotificationEntity; +import com.numberone.backend.domain.notification.entity.NotificationTag; +import com.numberone.backend.domain.notification.repository.NotificationRepository; import com.numberone.backend.domain.token.util.SecurityContextProvider; import com.numberone.backend.exception.notfound.NotFoundArticleException; import com.numberone.backend.exception.notfound.NotFoundCommentException; import com.numberone.backend.exception.notfound.NotFoundMemberException; +import com.numberone.backend.support.fcm.service.FcmMessageProvider; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -36,6 +40,8 @@ public class CommentService { private final ArticleParticipantRepository articleParticipantRepository; private final MemberRepository memberRepository; private final CommentLikeRepository commentLikeRepository; + private final NotificationRepository notificationRepository; + private final FcmMessageProvider fcmMessageProvider; @Transactional public CreateChildCommentResponse createChildComment( @@ -56,6 +62,19 @@ public CreateChildCommentResponse createChildComment( articleParticipantRepository.save(new ArticleParticipant(article, member)); + Member owner = memberRepository.findById(parentComment.getAuthorId()) + .orElseThrow(NotFoundMemberException::new); + String memberName = member.getNickName() != null ? member.getNickName() : member.getRealName(); + + String title = String.format(""" + 나의 댓글에 %s님이 댓글을 달았어요. + """, memberName); + String body = "대피로에 접속하여 확인하세요!"; + fcmMessageProvider.sendFcm(owner, title, body, NotificationTag.COMMUNITY); + notificationRepository.save( + new NotificationEntity(owner, NotificationTag.COMMUNITY, title, body, true) + ); + return CreateChildCommentResponse.of(childComment); } diff --git a/src/main/java/com/numberone/backend/domain/friendship/service/FriendshipService.java b/src/main/java/com/numberone/backend/domain/friendship/service/FriendshipService.java index a30fded6..45c2102b 100644 --- a/src/main/java/com/numberone/backend/domain/friendship/service/FriendshipService.java +++ b/src/main/java/com/numberone/backend/domain/friendship/service/FriendshipService.java @@ -7,7 +7,9 @@ import com.numberone.backend.domain.friendship.repository.FriendshipRepository; import com.numberone.backend.domain.member.entity.Member; import com.numberone.backend.domain.member.repository.MemberRepository; +import com.numberone.backend.domain.notification.entity.NotificationEntity; import com.numberone.backend.domain.notification.entity.NotificationTag; +import com.numberone.backend.domain.notification.repository.NotificationRepository; import com.numberone.backend.domain.token.util.SecurityContextProvider; import com.numberone.backend.exception.badrequest.InvalidInviteTypeException; import com.numberone.backend.exception.notfound.NotFoundFriendshipException; @@ -32,6 +34,7 @@ public class FriendshipService { private final MemberRepository memberRepository; private final FriendshipRepository friendshipRepository; private final FcmMessageProvider fcmMessageProvider; + private final NotificationRepository notificationRepository; @Transactional public InviteFriendResponse inviteFriend(Long memberId) { @@ -92,10 +95,15 @@ public SendFcmFriendResponse sendFcmToFriend(Long friendId) { String memberName = member.getRealName() != null ? member.getRealName() : member.getNickName(); String friendName = friend.getRealName() != null ? friend.getRealName() : friend.getNickName(); - String title = String.format("[ %s님! %s님께서 회원님이 안전한지 걱정하고 있어요. 🥲]", friendName, memberName); - String body = String.format(" %s님께 현재 상태를 보내볼까요? ", memberName); - + String title = "긴급!"; + String body = String.format(""" + %s님이 안부를 궁금해하고 있어요. + 걱정하고 있을 %s님을 위해 빨리 연락해주세요! + """, memberName, memberName); fcmMessageProvider.sendFcm(friend, title, body, NotificationTag.FAMILY); + notificationRepository.save( + new NotificationEntity(friend, NotificationTag.FAMILY, title, body, true) + ); return SendFcmFriendResponse.builder() .title(title) diff --git a/src/main/java/com/numberone/backend/domain/like/service/LikeService.java b/src/main/java/com/numberone/backend/domain/like/service/LikeService.java index f215355e..b967f47d 100644 --- a/src/main/java/com/numberone/backend/domain/like/service/LikeService.java +++ b/src/main/java/com/numberone/backend/domain/like/service/LikeService.java @@ -10,7 +10,9 @@ import com.numberone.backend.domain.like.repository.CommentLikeRepository; import com.numberone.backend.domain.member.entity.Member; import com.numberone.backend.domain.member.repository.MemberRepository; +import com.numberone.backend.domain.notification.entity.NotificationEntity; import com.numberone.backend.domain.notification.entity.NotificationTag; +import com.numberone.backend.domain.notification.repository.NotificationRepository; import com.numberone.backend.domain.token.util.SecurityContextProvider; import com.numberone.backend.exception.conflict.AlreadyLikedException; import com.numberone.backend.exception.conflict.AlreadyUnLikedException; @@ -40,6 +42,7 @@ public class LikeService { private final CommentRepository commentRepository; private final MemberRepository memberRepository; private final FcmMessageProvider fcmMessageProvider; + private final NotificationRepository notificationRepository; private final Integer BEST_ARTICLE_LIKE_COUNT = 20; @@ -57,12 +60,19 @@ public Integer increaseArticleLike(Long articleId) { article.increaseLikeCount(); articleLikeRepository.save(new ArticleLike(member, article)); - if (article.getLikeCount() >= BEST_ARTICLE_LIKE_COUNT) { - Long ownerId = article.getArticleOwnerId(); - Member owner = memberRepository.findById(ownerId) - .orElseThrow(NotFoundMemberException::new); - fcmMessageProvider.sendFcm(owner, BEST_ARTICLE_FCM_ALARM, NotificationTag.COMMUNITY); - } + Long ownerId = article.getArticleOwnerId(); + Member owner = memberRepository.findById(ownerId) + .orElseThrow(NotFoundMemberException::new); + + String memberName = member.getNickName() != null ? member.getNickName() : member.getRealName(); + String title = String.format(""" + 나의 게시글에 %s님이 좋아요를 눌렀어요. + """, memberName); + String body = "대피로에 접속하여 확인하세요!"; + fcmMessageProvider.sendFcm(owner, title, body, NotificationTag.COMMUNITY); + notificationRepository.save( + new NotificationEntity(owner, NotificationTag.COMMUNITY, title, body, true) + ); return article.getLikeCount(); } @@ -101,6 +111,22 @@ public Integer increaseCommentLike(Long commentId) { commentEntity.increaseLikeCount(); commentLikeRepository.save(new CommentLike(member, commentEntity)); + + + Long ownerId = commentEntity.getAuthorId(); + Member owner = memberRepository.findById(ownerId) + .orElseThrow(NotFoundMemberException::new); + + String memberName = member.getNickName() != null ? member.getNickName() : member.getRealName(); + String title = String.format(""" + 나의 댓글에 %s님이 좋아요를 눌렀어요. + """, memberName); + String body = "대피로에 접속하여 확인하세요!"; + fcmMessageProvider.sendFcm(owner, title, body, NotificationTag.COMMUNITY); + notificationRepository.save( + new NotificationEntity(owner, NotificationTag.COMMUNITY, title, body, true) + ); + return commentEntity.getLikeCount(); } diff --git a/src/main/java/com/numberone/backend/support/fcm/service/FcmMessageProvider.java b/src/main/java/com/numberone/backend/support/fcm/service/FcmMessageProvider.java index d8f8911d..fc77280e 100644 --- a/src/main/java/com/numberone/backend/support/fcm/service/FcmMessageProvider.java +++ b/src/main/java/com/numberone/backend/support/fcm/service/FcmMessageProvider.java @@ -2,15 +2,9 @@ import com.google.firebase.messaging.*; import com.numberone.backend.domain.member.entity.Member; -import com.numberone.backend.domain.notification.entity.NotificationEntity; import com.numberone.backend.domain.notification.entity.NotificationTag; -import com.numberone.backend.domain.notification.repository.NotificationRepository; -import com.numberone.backend.exception.conflict.FirebaseMessageSendException; -import com.numberone.backend.support.fcm.dto.FcmNotificationDto; -import com.numberone.backend.support.notification.NotificationMessage; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.time.LocalDateTime; @@ -23,40 +17,6 @@ @Component @RequiredArgsConstructor public class FcmMessageProvider { - private final NotificationRepository notificationRepository; - - public void sendFcm(Member member, NotificationMessage notificationMessage, NotificationTag tag) { - String token = member.getFcmToken(); - if (Objects.isNull(token)) { - log.error("해당 회원의 fcm 토큰이 존재하지 않아, 푸시알람을 전송할 수 없습니다."); - // todo : 예외 핸들링 - return; - } - - String title = notificationMessage.getTitle(); - String body = member.getNickName() + "님, " + notificationMessage.getBody(); - - Message message = Message.builder() - .putData("time", LocalDateTime.now().toString()) - .setNotification( - Notification.builder() - .setTitle(title) - .setBody(body) - .build() - ) - .setToken(token) - .build(); - try { - //String response = FirebaseMessaging.getInstance().send(message); - FirebaseMessaging.getInstance().send(message); - notificationRepository.save(new NotificationEntity(member, tag, title, body, true)); - log.info("Fcm 푸시 알람을 성공적으로 전송하였습니다."); - log.info("[FCM Message] {} : {}", title, body); - } catch (Exception e) { - notificationRepository.save(new NotificationEntity(member, tag, title, body, false)); - log.error("Fcm 푸시 알람을 전송하는 도중에 에러가 발생했습니다. {}", e.getMessage()); - } - } public void sendFcm(Member member, String title, String body, NotificationTag tag) { String token = member.getFcmToken(); @@ -79,54 +39,16 @@ public void sendFcm(Member member, String title, String body, NotificationTag ta try { //String response = FirebaseMessaging.getInstance().send(message); FirebaseMessaging.getInstance().send(message); - notificationRepository.save(new NotificationEntity(member, tag, title, body, true)); log.info("Fcm 푸시 알람을 성공적으로 전송하였습니다."); log.info("[FCM Message] {} : {}", title, body); - } catch (Exception e) { - notificationRepository.save(new NotificationEntity(member, tag, title, body, false)); - log.error("Fcm 푸시 알람을 전송하는 도중에 에러가 발생했습니다. {}", e.getMessage()); - } - } - - public void sendFcmToMembers(List tokens, FcmNotificationDto fcmDto) { - List messages = tokens.stream().map( - token -> Message.builder() - .putData("time", LocalDateTime.now().toString()) - .setNotification( - Notification.builder() - .setTitle(fcmDto.getTitle()) - .setBody(fcmDto.getBody()) - .setImage(fcmDto.getImageUrl()) - .build() - ) - .setToken(token) - .build() - ).toList(); - - try { - BatchResponse response = FirebaseMessaging.getInstance().sendAll(messages); - if (response.getFailureCount() > 0) { - /* 발송 실패한 경우 핸들링 */ - List responses = response.getResponses(); - List failedTokens = new ArrayList<>( - IntStream.range(0, responses.size()) - .filter(idx -> !responses.get(idx).isSuccessful()) - .mapToObj(tokens::get) - .toList() - ); - - log.error("FCM 메세징 실패 토큰 목록 출력: {}", failedTokens); - } - log.info("Fcm 푸시 알람을 전송하였습니다."); } catch (Exception e) { log.error("Fcm 푸시 알람을 전송하는 도중에 에러가 발생했습니다. {}", e.getMessage()); - throw new FirebaseMessageSendException(); } } public void sendFcmToMembers(List tokens, String title, String body, NotificationTag tag) { log.info("{} 건의 푸시알람을 전송합니다.", tokens.size()); - if(tokens.isEmpty()) return; + if (tokens.isEmpty()) return; List messages = tokens.stream().map( token -> Message.builder() .putData("time", LocalDateTime.now().toString()) @@ -157,7 +79,6 @@ public void sendFcmToMembers(List tokens, String title, String body, Not log.info("Fcm 푸시 알람을 전송하였습니다."); } catch (Exception e) { log.error("Fcm 푸시 알람을 전송하는 도중에 에러가 발생했습니다. {}", e.getMessage()); - //throw new FirebaseMessageSendException(); } }