Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] feat: 유저 FCM 로직 변경(#471) #472

Merged
merged 11 commits into from
Oct 11, 2023
Merged

[BE] feat: 유저 FCM 로직 변경(#471) #472

merged 11 commits into from
Oct 11, 2023

Conversation

BGuga
Copy link
Member

@BGuga BGuga commented Sep 27, 2023

📌 관련 이슈

✨ PR 세부 내용

  1. 로그인 시 중복 FCM 확인
  2. 회원가입 시 FCM 저장 ( 중복 확인 과정을 생략합니다 )
  3. 탈퇴 시 유저 FCM 삭제
  4. 모든 요청이 성공했을 시 예외를 발생시키지 않도록 변경

작업 완료했습니다.
MemberFCM table 에 (member_id, fcm_token) unique 제약 조건을 걸어주어

기존 쿼리

List<MemberFCM> memberFCM = memberFCMRepository.findByMemberId(memberId);

새로운 쿼리

Optional<MemberFCM> memberFCM = memberFCMRepository.findMemberFCMByMemberIdAndFcmToken(memberId, fcmToken);

가 인덱스 기반으로 쿼리를 날릴 수 있도록 변경하였고 unique 제약 조건으로 데이터 정합성도 맞췄습니다.

fcm 생성, 삭제에 대한 전체적인 흐름이
로그인 : fcm 존재 확인 후 저장 ✅
로그아웃: fcm ❌
회원탈퇴: fcm 삭제 ✅
회원가입: fcm 저장 ✅

@BGuga BGuga linked an issue Sep 27, 2023 that may be closed by this pull request
@github-actions
Copy link

github-actions bot commented Sep 27, 2023

Unit Test Results

  75 files    75 suites   13s ⏱️
234 tests 234 ✔️ 0 💤 0
238 runs  238 ✔️ 0 💤 0

Results for commit 531f4a4.

♻️ This comment has been updated with latest results.

@seokjin8678 seokjin8678 added the BE 백엔드에 관련된 작업 label Sep 27, 2023
@BGuga BGuga self-assigned this Sep 27, 2023
@xxeol2 xxeol2 added the ☢️ DB 데이터베이스에 변경이 있는 작업 label Sep 27, 2023
Copy link
Collaborator

@seokjin8678 seokjin8678 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰 남겼습니다!

Comment on lines 47 to 50
if (memberFCM.isPresent()) {
return;
}
memberFCMRepository.save(new MemberFCM(memberId, fcmToken));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (memberFCM.isPresent()) {
return;
}
memberFCMRepository.save(new MemberFCM(memberId, fcmToken));
if (memberFCM.isEmpty()) {
memberFCMRepository.save(new MemberFCM(memberId, fcmToken));
}

다음과 같이 해도 좋을 것 같아요

Comment on lines 86 to 88
if (failSend.isEmpty()) {
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (failSend.isEmpty()) {
return;
}
if (batchResponse.getFailureCount() > 0) {
List<SendResponse> failSend = batchResponse.getResponses().stream()
.filter(sendResponse -> !sendResponse.isSuccessful())
.toList();
log.warn("member {} 에 대한 다음 요청들이 실패했습니다. {}", memberId, failSend);
}

다음과 같이 최적화 할 수 있을 것 같아요!

Copy link
Member

@xxeol2 xxeol2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

깔꼼하네요 👍

Comment on lines 41 to 47
String accessToken = response.accessToken();
String fcmToken = request.fcmToken();
if (response.isNew()) {
memberFCMService.saveNewMemberFCM(accessToken, fcmToken);
return;
}
memberFCMService.saveOriginMemberFCM(accessToken, fcmToken);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분 isNew 여부 boolean으로 Service에 파라미터로 보내주고 Service에서 분기타는거 어떤가요??

Copy link
Collaborator

@seokjin8678 seokjin8678 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

간단하게 리뷰 남겼습니다!
최신 dev 브랜치로 가져와서 롬복만 적용하면 될 것 같아요!
고생하셨습니다!

@@ -80,11 +77,11 @@ private AndroidNotification createAndroidNotification(String channelId) {
}

private void checkAllSuccess(BatchResponse batchResponse, Long memberId) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이제 더 이상 check 하는 것이 아니니까 logFailResponses 정도로 해도 좋겠네요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요 부분이 애쉬 PR에 반영돼어서 애쉬 PR을 머지한 후에 conflict 해결하면서 빠진 부분 채워 넣을게요!

public void sendMessages(List<Message> messages, FCMChannel channel) {
        try {
            BatchResponse response = firebaseMessaging.sendAll(messages);
            checkAllSuccess(response, channel);
        } catch (FirebaseMessagingException e) {
            log.warn("[FCM: {}] 전송 실패: {}", channel, e.getMessagingErrorCode());
        }
    }

Comment on lines 30 to 37
@Transactional(readOnly = true)
public MemberFCMsResponse findMemberFCM(Long memberId) {
List<MemberFCM> memberFCM = memberFCMRepository.findByMemberId(memberId);
if (memberFCM.size() < LEAST_MEMBER_FCM) {
log.error("member {} 의 FCM 토큰이 발급되지 않았습니다.", memberId);
throw new InternalServerException(ErrorCode.FCM_NOT_FOUND);
if (memberFCM.isEmpty()) {
log.warn("member {} 의 FCM 토큰이 발급되지 않았습니다.", memberId);
}
return MemberFCMsResponse.from(memberFCM);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추후 사용자의 FCM 등록 요청이 별도 API로 분리되게 된다면 해당 로그는 더 이상 찍을 필요가 없겠네요!

@DeleteMapping
@SecurityRequirement(name = "bearerAuth")
@Operation(description = "회원 탈퇴 요청을 보낸다.", summary = "유저 회원 탈퇴")
public ResponseEntity<Void> deleteMember(@Member Long memberId) {
authFacadeService.deleteMember(memberId);
memberFCMService.deleteMemberFCM(memberId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FCM에 관한 의존성 분리를 하더라도 회원이 탈퇴하면 회원의 FCM을 삭제 해야하기 때문에 Auth 도매인이 FCM 도메인을 의존하게 되는 문제는 여전히 발생하겠네요.
이 부분은 DB의 Cascade로 풀어야 하나 고민이 드네요. (회원의 삭제가 Soft-delete라 전파가 될지도 모르겠네요. 😂)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로그인 과정에서 분리된 것이지 패키지 의존성으로 보면 그렇네요!!
저희가 eventListener를 사용하지 않았던 것이 결국 authFacadeService에 fcmToken 값이 들어갔기 때문인데 controller 에서 event 를 발행하면 authService에 fcmToken을 넘겨주지 않아도 되고 의존성도 분리되니 해당 방법은 어떠신가요?

Copy link
Collaborator

@carsago carsago left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굿

@BGuga BGuga merged commit a5193e5 into dev Oct 11, 2023
3 checks passed
@BGuga BGuga deleted the feat/#471 branch October 11, 2023 06:41
BGuga added a commit that referenced this pull request Oct 17, 2023
* fix: 유저의 fcm 요청이 모두 성공했을 때 예외를 발생시키지 않는다

* feat: 회원 탈퇴 시 memberFCM 삭제 및 로그인 시 memberFCM 저장 로직 구현

* chore: hard wrap 120 적용

* feat: 회원가입과 로그인 여부에 따라 FCM 로직을 분기한다

* feat: 회원가입 FCM 저장 로직 비동기 처리

* chore: 외래키 제약 조건 추가 분리

* feat: memberFCM 토큰이 없거나 메세징이 실패했을 경우에 log 만 작성하도록 변경

* refactor: 로직 개선

* test: 로직 변경에 따른 검증 내용 변경

* refactor: 신규 가입 여부에 따른 fcm 발행 관리를 Service 에게 위임

* chore: flyway 버전 변경
BGuga added a commit that referenced this pull request Oct 17, 2023
* fix: 유저의 fcm 요청이 모두 성공했을 때 예외를 발생시키지 않는다

* feat: 회원 탈퇴 시 memberFCM 삭제 및 로그인 시 memberFCM 저장 로직 구현

* chore: hard wrap 120 적용

* feat: 회원가입과 로그인 여부에 따라 FCM 로직을 분기한다

* feat: 회원가입 FCM 저장 로직 비동기 처리

* chore: 외래키 제약 조건 추가 분리

* feat: memberFCM 토큰이 없거나 메세징이 실패했을 경우에 log 만 작성하도록 변경

* refactor: 로직 개선

* test: 로직 변경에 따른 검증 내용 변경

* refactor: 신규 가입 여부에 따른 fcm 발행 관리를 Service 에게 위임

* chore: flyway 버전 변경
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BE 백엔드에 관련된 작업 ☢️ DB 데이터베이스에 변경이 있는 작업
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BE] FCM 로직 변경
4 participants