diff --git a/src/main/java/com/assu/server/domain/deviceToken/entity/DeviceToken.java b/src/main/java/com/assu/server/domain/deviceToken/entity/DeviceToken.java index 4d98454e..f0ce00f5 100644 --- a/src/main/java/com/assu/server/domain/deviceToken/entity/DeviceToken.java +++ b/src/main/java/com/assu/server/domain/deviceToken/entity/DeviceToken.java @@ -18,7 +18,7 @@ public class DeviceToken extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="member_id", nullable=false) private Member member; - @Column(nullable=false, length=200, unique=true) + @Column(nullable=false, length=200) private String token; @Setter diff --git a/src/main/java/com/assu/server/domain/deviceToken/repository/DeviceTokenRepository.java b/src/main/java/com/assu/server/domain/deviceToken/repository/DeviceTokenRepository.java index ee0c8349..95c1fcfb 100644 --- a/src/main/java/com/assu/server/domain/deviceToken/repository/DeviceTokenRepository.java +++ b/src/main/java/com/assu/server/domain/deviceToken/repository/DeviceTokenRepository.java @@ -20,4 +20,10 @@ public interface DeviceTokenRepository extends JpaRepository void deactivateTokens(@Param("tokens") List tokens); Optional findByToken(String token); + + // 같은 회원 + 같은 토큰 있는지 확인 + Optional findByMemberIdAndToken(Long memberId, String token); + + // 같은 회원이 가진 모든 토큰 (비활성화용) + List findAllByMemberId(Long memberId); } diff --git a/src/main/java/com/assu/server/domain/deviceToken/service/DeviceTokenServiceImpl.java b/src/main/java/com/assu/server/domain/deviceToken/service/DeviceTokenServiceImpl.java index 9d4cabb1..fe37ddd4 100644 --- a/src/main/java/com/assu/server/domain/deviceToken/service/DeviceTokenServiceImpl.java +++ b/src/main/java/com/assu/server/domain/deviceToken/service/DeviceTokenServiceImpl.java @@ -21,19 +21,41 @@ public class DeviceTokenServiceImpl implements DeviceTokenService { @Transactional @Override public Long register(String tokenId, Long memberId) { - Member member = memberRepository.findMemberById(memberId).orElseThrow( - () -> new GeneralException(ErrorStatus.NO_SUCH_MEMBER) - ); - if (member == null) { - throw new DatabaseException(ErrorStatus.NO_SUCH_MEMBER); + Member member = memberRepository.findMemberById(memberId) + .orElseThrow(() -> new GeneralException(ErrorStatus.NO_SUCH_MEMBER)); + + // 1) 같은 회원 + 같은 토큰이 이미 있으면 → active = true 로만 복구 + // (가장 정확한 쿼리: findByMemberIdAndToken) + var sameTokenOpt = deviceTokenRepository.findByMemberIdAndToken(memberId, tokenId); + if (sameTokenOpt.isPresent()) { + DeviceToken exist = sameTokenOpt.get(); + exist.setActive(true); + deviceTokenRepository.save(exist); + return exist.getId(); + } + + // 2) 같은 회원 + 다른 토큰 → 그 회원의 기존 active 토큰 전부 비활성화 + // (현재 보유 메서드 활용: 활성 토큰 문자열 가져와 deactivate) + var activeTokens = deviceTokenRepository.findActiveTokensByMemberId(memberId); + if (!activeTokens.isEmpty()) { + // 현재 등록하려는 tokenId 와 다른 것들만 비활성화 + var toDeactivate = activeTokens.stream() + .filter(t -> !t.equals(tokenId)) + .toList(); + if (!toDeactivate.isEmpty()) { + deviceTokenRepository.deactivateTokens(toDeactivate); + } } - DeviceToken dt = deviceTokenRepository.findByToken(tokenId) - .map(deviceToken -> { deviceToken.setActive(true); return deviceToken; }) - .orElse(DeviceToken.builder().member(member).token(tokenId).active(true).build()); - deviceTokenRepository.save(dt); + // 3) 새 토큰 insert (다른 회원이 같은 토큰을 갖고 있어도 상관 없이 insert) + DeviceToken newToken = DeviceToken.builder() + .member(member) + .token(tokenId) + .active(true) + .build(); + deviceTokenRepository.save(newToken); - return dt.getId(); + return newToken.getId(); } @Transactional