-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* feat: DB에서 사용자의 FCM Token 목록 가져와 send Message #24 - FCMToken Entity 추가 - FCMTokenService.getTokenListByUser: User의 이메일 주소로 FCMToken 목록을 조회하여 토큰 문자열의 목록을 반환 - ImageService.notifyImageComplete * [Resolves #34] 대표 이미지 선택 API (#36) #34 * fix: Diary에서 대표 이외 나머지 후보 삭제 NullPointError 수정 #34 * chore: log.debug() 임시 적용 (#39) #38 * fix: Diary의 태그 (shortcontent)가 null 일 때 Response DTO의 태그에 Empty List 반환하게 수정 * fix: 일기 작성 후 ~ 이미지 생성 전 상태를 확인하도록 수정 - 후보 이미지 목록 조회 - 대표 이미지 선택 * fix: 일기 작성 후 ~ 이미지 생성 전 상태를 확인하도록 수정 - 후보 이미지 목록 조회 - 대표 이미지 선택 * [Resolves #33] 일기 수정 및 삭제 API (#42) * feat: 일기 삭제 API #33 * feat: 일기 수정 API #33 * Docs: 일기 수정 API Swagger #33 * fix: PathVariable 오탈자 수정 * feat: FCM Token 등록 API #24 * feat: 이미지 생성 완료 시 클라이언트에 Notify #24 * feat: Notification 테스트용 API #24 * fix: FCM Token이 하나도 없을 경우 체크 #24
- Loading branch information
Showing
11 changed files
with
328 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package grimuri.backend.domain.fcm; | ||
|
||
import grimuri.backend.domain.BaseTimeEntity; | ||
import grimuri.backend.domain.user.User; | ||
import lombok.*; | ||
|
||
import javax.persistence.*; | ||
import java.time.LocalDateTime; | ||
|
||
@Entity | ||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@Builder | ||
public class FCMToken extends BaseTimeEntity { | ||
|
||
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long fcmTokenId; | ||
|
||
@Column(nullable = false) | ||
private String token; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "user_pk", nullable = false) | ||
private User user; | ||
|
||
@Column | ||
private LocalDateTime lastLogin; | ||
|
||
@Column | ||
private Long failCount; | ||
|
||
public void setLastLogin(LocalDateTime localDateTime) { | ||
this.lastLogin = localDateTime; | ||
} | ||
|
||
public void setFailCount(Long count) { | ||
this.failCount = count; | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
src/main/java/grimuri/backend/domain/fcm/FCMTokenController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package grimuri.backend.domain.fcm; | ||
|
||
import grimuri.backend.domain.diary.dto.DiaryResponseDto; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.media.Content; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.ResponseStatus; | ||
|
||
public interface FCMTokenController { | ||
|
||
@Operation( | ||
summary = "Notification 테스트", | ||
description = "로그인된 사용자에게 Notification을 테스트한다. Diary는 존재하지 않아도 된다.", | ||
tags = { "FCMTokenController" } | ||
) | ||
@ApiResponses({ | ||
@ApiResponse(responseCode = "200", description = "Ok.", | ||
content = @Content(schema = @Schema(implementation = String.class))), | ||
@ApiResponse(responseCode = "401", description = "Unauthorized, 권한 없음.", | ||
content = @Content(schema = @Schema(hidden = true))), | ||
@ApiResponse(responseCode = "500", description = "Internal Server Error", | ||
content = @Content(schema = @Schema(hidden = true))) | ||
}) | ||
@ResponseStatus(HttpStatus.OK) | ||
ResponseEntity<?> testNotification(@RequestParam Long diaryId, @RequestParam String diaryTitle); | ||
} |
43 changes: 43 additions & 0 deletions
43
src/main/java/grimuri/backend/domain/fcm/FCMTokenControllerImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package grimuri.backend.domain.fcm; | ||
|
||
import com.google.firebase.messaging.FirebaseMessagingException; | ||
import grimuri.backend.domain.image.ImageService; | ||
import grimuri.backend.domain.user.User; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import java.util.List; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
@RequestMapping("/api/v1/fcm") | ||
public class FCMTokenControllerImpl implements FCMTokenController { | ||
|
||
private final ImageService imageService; | ||
private final FCMTokenRepository fcmTokenRepository; | ||
|
||
@GetMapping("/notification-test") | ||
@Override | ||
public ResponseEntity<?> testNotification(@RequestParam Long diaryId, @RequestParam String diaryTitle) { | ||
User loginUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); | ||
|
||
List<FCMToken> tokenList = fcmTokenRepository.findAllByUser_Email(loginUser.getEmail()); | ||
try { | ||
imageService.notifyImageComplete(tokenList, diaryId, diaryTitle); | ||
} catch (FirebaseMessagingException e) { | ||
e.printStackTrace(); | ||
|
||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); | ||
} | ||
|
||
return ResponseEntity.status(HttpStatus.OK).body("success"); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/grimuri/backend/domain/fcm/FCMTokenRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package grimuri.backend.domain.fcm; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
@Repository | ||
public interface FCMTokenRepository extends JpaRepository<FCMToken, Long> { | ||
|
||
List<FCMToken> findAllByUser_Email(String email); | ||
|
||
Optional<FCMToken> findByToken(String tokenStr); | ||
} |
86 changes: 86 additions & 0 deletions
86
src/main/java/grimuri/backend/domain/fcm/FCMTokenService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package grimuri.backend.domain.fcm; | ||
|
||
import grimuri.backend.domain.user.User; | ||
import grimuri.backend.domain.user.UserRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.server.ResponseStatusException; | ||
|
||
import javax.transaction.Transactional; | ||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
@Service | ||
@Transactional | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class FCMTokenService { | ||
|
||
private final FCMTokenRepository fcmTokenRepository; | ||
private final UserRepository userRepository; | ||
|
||
/** | ||
* FCM Token - 사용자 정보를 DB에 저장한다. 기존에 존재하는 Token-사용자 정보라면 마지막 로그인 시간을 갱신한다. | ||
* Token은 존재하지만 사용자 정보가 다르다면 해당 정보를 삭제하고 새로운 사용자 정보로 FCM Token을 재생성한다. | ||
* 아예 존재하지 않는 FCM Token - 사용자 정보라면 새로 생성하여 저장한다. | ||
* @param email FCM Token 정보를 저장할 사용자의 email (PK) | ||
* @param fcmTokenStr FCM Token 문자열 | ||
*/ | ||
public void registerFCMToken(String email, String fcmTokenStr) { | ||
// email로 사용자 엔티티 조회 | ||
User user = userRepository.findById(email).orElseThrow(() -> { | ||
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "user email not found"); | ||
}); | ||
|
||
// 해당 토큰이 DB에 존재하는지 확인 | ||
fcmTokenRepository.findByToken(fcmTokenStr).ifPresentOrElse( | ||
// 존재하면, 사용자의 것인지 확인 | ||
fcmToken -> { | ||
if (fcmToken.getUser().getEmail().equals(email)) { | ||
// 사용자의 것이라면 마지막 로그인 시간 갱신 | ||
fcmToken.setLastLogin(LocalDateTime.now()); | ||
} else { | ||
// 사용자의 것이 아니라면 기존 토큰정보 삭제 후 재생성 | ||
fcmTokenRepository.delete(fcmToken); | ||
createNewTokenAndSave(fcmTokenStr, user); | ||
} | ||
}, | ||
// 없으면 새로 등록 | ||
() -> { | ||
createNewTokenAndSave(fcmTokenStr, user); | ||
} | ||
); | ||
} | ||
|
||
/** | ||
* 토큰 문자열과 사용자 엔티티로 FCMToken 엔티티를 새로 생성하여 저장한다. | ||
* @param fcmTokenStr FCM Token 문자열 | ||
* @param user 사용자 엔티티 | ||
*/ | ||
private void createNewTokenAndSave(String fcmTokenStr, User user) { | ||
FCMToken newToken = FCMToken.builder() | ||
.token(fcmTokenStr) | ||
.user(user) | ||
.lastLogin(LocalDateTime.now()) | ||
.failCount(0L) | ||
.build(); | ||
|
||
fcmTokenRepository.save(newToken); | ||
} | ||
|
||
/** | ||
* 사용자의 이메일 주소를 통해 FCM Token의 목록을 조회하여 반환한다. | ||
* @param email FCM Token 목록을 조회할 사용자의 이메일 | ||
* @return FCM 토큰(String)의 목록 | ||
*/ | ||
public List<String> getTokenListByUser(String email) { | ||
List<FCMToken> tokenList = fcmTokenRepository.findAllByUser_Email(email); | ||
|
||
return tokenList.stream() | ||
.map(FCMToken::getToken) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.