Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@ public interface DeviceTokenRepository extends JpaRepository<DeviceToken, Long>
void deactivateTokens(@Param("tokens") List<String> tokens);

Optional<DeviceToken> findByToken(String token);

// 같은 회원 + 같은 토큰 있는지 확인
Optional<DeviceToken> findByMemberIdAndToken(Long memberId, String token);

// 같은 회원이 가진 모든 토큰 (비활성화용)
List<DeviceToken> findAllByMemberId(Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down