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 을 통해 유저 핸드폰에 입장 처리 완료 메시지를 보낸다(#444) #449

Merged
merged 33 commits into from
Sep 26, 2023

Conversation

BGuga
Copy link
Member

@BGuga BGuga commented Sep 15, 2023

📌 관련 이슈

✨ PR 세부 내용

참고한 글을 다음과 같습니다.
글 1 , 글2

구현한 내용에 대한 설명은 다음과 같습니다.

  1. FirebaseMessaging 을 통해서 Android Client 에게 메시지를 보낼 수 있습니다.
  2. Android Client 에 대한 식별자는 fcmToken 이며, 해당 데이터를 가진 MemberFCM Entity 로 설계하였습니다.
  3. fcmToken 은 로그인 요청 시 LoginRequest dto 로 넘어옵니다.
  4. fcmToken의 만료는 유저가 앱을 지웠거나, 내부 데이터를 지울 때 등 자연적인 상황에서는 발생하지 않습니다. Reference

여기서 추가적으로 논의해야할 포인트는

  1. 멤버의 모든 FCM 을 지우지 않기 위해서는 멤버의 디바이스에 대한 식별자가 필요합니다.
    유저가 여러 디바이스에서 로그인할 경우 한 유저에 대한 FCM 은 다수가 저장될 수 있습니다.
    현재는 로그인 시 넘어오는 FCM 으로 유저의 모든 FCM 을 지우고 새로운 FCM 하나로 대체하는 방식으로 구현해두었습니다.
  2. channelId로 이벤트 구분 하는 로직 필요
    Token 을 통해 유저를 식별할 수 있었다면 해당 유저에게 어떤 이벤트를 보낼 것인가는 Channel 이란 단위로 구분할 수 있습니다.
    해당 개념을 반영한 부분은 다음과 같습니다.
    추후에 이벤트가 늘어남에 따라서 이벤트에 대한 명세를 맞추면서 개발을 지속해 나가야할 것 같습니다.
    현재는 이벤트 하나이기 때문에 이런 구분이 필요없기에 null 을 넣어놨습니다.

@github-actions
Copy link

github-actions bot commented Sep 15, 2023

Unit Test Results

  69 files    69 suites   12s ⏱️
193 tests 193 ✔️ 0 💤 0
196 runs  196 ✔️ 0 💤 0

Results for commit 38476b3.

♻️ This comment has been updated with latest results.

@BGuga BGuga self-assigned this Sep 15, 2023
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.

수고하셨습니다아 !!
멋지네요..

@@ -23,7 +23,7 @@ public AuthFacadeService(AuthService authService, OAuth2Clients oAuth2Clients,
}

public LoginResponse login(LoginRequest request) {
LoginMemberDto loginMember = authService.login(getUserInfo(request));
LoginMemberDto loginMember = authService.login(getUserInfo(request), request.fcmToken());
Copy link
Member

Choose a reason for hiding this comment

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

사소한 제안인데 getUesrInfo(request)를 인라인 말고 변수 추출하는건 어떨까요?
Oauth2Clients에게 요청을 하고 -> tx 시작하고 -> 토큰 발급하고
이 흐름에서 첫번째 단계가 눈에 잘 보이지 않는 것 같아요

Copy link
Member Author

Choose a reason for hiding this comment

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

인정인정 무조건 줄 수 줄이는게 좋은건 아닌 것 같아요 👍

Comment on lines 40 to 45
private void enrollFcm(Member member, String fcmToken) {
// TODO : 멤버의 모든 FCM 을 지우지 않기 위해서는 멤버의 디바이스에 대한 식별자가 필요합니다.
deleteFCM(member);
memberFCMRepository.save(new MemberFCM(member, fcmToken));
}

Copy link
Member

Choose a reason for hiding this comment

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

delete해주는건 해당 기기에서의 이전 FCM 토큰을 지워주기 위해서일까요 ?!
꼼꼼한 처리 좋네요 👍

@@ -50,6 +55,7 @@ public TicketValidationResponse validate(TicketValidationRequest request) {
EntryCodePayload entryCodePayload = entryCodeManager.extract(request.code());
MemberTicket memberTicket = findMemberTicket(entryCodePayload.getMemberTicketId());
memberTicket.changeState(entryCodePayload.getEntryState());
publisher.publishEvent(new EntryProcessEvent(memberTicket.getOwner().getId()));
Copy link
Member

Choose a reason for hiding this comment

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

어떤 memberTicket에 대한 fcm인지는 구분해주지 않아도 되나요?!
(fcm 메세지에 memberTicketId는 함께 보내지 않아도 되나요?)

Copy link
Member Author

Choose a reason for hiding this comment

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

지금은 이벤트가 딱 하나니까 그냥 이벤트가 날라왔다? -> 다음 화면으로 이동 이렇게 구현되어 있어요!!
애쉬가 말씀 주신 것처럼 memberTicketId 를 같이 보내서 android 에서도 검증을 할 수 있게 만들면 더 좋겠네요 ㅎㅎ
이건 안드로이드 분들과 한번 같이 이야기해보져

Comment on lines 39 to 43
private void validate(Member member, String fcmToken) {
if (member == null || fcmToken == null) {
throw new IllegalArgumentException("MemberFCM 은 허용되지 않은 null 값으로 생성할 수 없습니다.");
}
}
Copy link
Member

Choose a reason for hiding this comment

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

얘는 왜 InternalServerException이 아닌 IllegalArgumentException인가요?

Copy link
Member Author

Choose a reason for hiding this comment

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

도메인 validation 을 잡을 때 이게 BadRequest 인지 InteralServerException 인지 어떻게 결정하면 좋을까 고민이 됐습니다.
또한 도메인 안에서 Http status 가 결정되는 것이 맞나..? 라는 생각을해서 도메인에서 표준 예외를 발생시키도록 만들었습니다.
그 에외에 대한 판단은 Service 에서 해당 도메인의 생성에서 예외가 발생한 것은 InteralServerException 이다, BadRequest 이다. 이렇게 판단하면 좋지 않을까 생각했었습니다!!

Copy link
Collaborator

Choose a reason for hiding this comment

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

kotlin을 썼으면 이런일이 없었을텐데 ㅠㅠ

Comment on lines 26 to 34
private Optional<FirebaseApp> defaultFirebaseApp() {
List<FirebaseApp> firebaseAppList = FirebaseApp.getApps();
if (firebaseAppList == null || firebaseAppList.isEmpty()) {
return Optional.empty();
}
return firebaseAppList.stream()
.filter(firebaseApp -> firebaseApp.getName().equals(FirebaseApp.DEFAULT_APP_NAME))
.findAny();
}
Copy link
Member

Choose a reason for hiding this comment

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

사용하는 메서드 아래에 위치시키면 좋을 것 같아요!

Copy link
Member Author

Choose a reason for hiding this comment

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

앗 ㅋㅋ 감사합니다

Comment on lines 1 to 16
create table if not exists member_fcm
(
id bigint not null auto_increment,
created_at datetime(6),
updated_at datetime(6),
member_id bigint,
fcm_token varchar(255),
primary key (id)
) engine innodb
default charset = utf8mb4
collate = utf8mb4_0900_ai_ci;

alter table member_fcm
add constraint fk_member_fcm__member
foreign key (member_id)
references member (id);
Copy link
Member

Choose a reason for hiding this comment

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

#443 PR에 V3가 있는데, merge할 때 주의해야할 것 같네요!!

Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 이슈 때문에 버전을 V202309180138 이렇게 사용하기도 한다네요

// then
assertThat(actual).contains(expect);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

EOF!!
몇몇 파일에 EOF 문구가 떠요!! 전체적으로 확인해주세용

Copy link
Member Author

Choose a reason for hiding this comment

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

edu 설정을 빼먹었네요 ㅠㅠ 설정 달아놓고 개행 추가했어요!

Copy link
Member

Choose a reason for hiding this comment

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

edu도 이 기능이 지원돼요 ? 😁

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 3 to 5
public record EntryProcessEvent(Long memberId) {

}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
public record EntryProcessEvent(Long memberId) {
}
public record EntryProcessEvent(
Long memberId) {
}

Comment on lines 26 to 28
private final FirebaseMessaging firebaseMessaging;

private final MemberFCMService memberFCMService;
Copy link
Member

Choose a reason for hiding this comment

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

이친구들 공백 없이 붙여줘도 괜찮을 것 같아요

Copy link
Member Author

Choose a reason for hiding this comment

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

앗 싸웠었나봐요 붙혀뒀습니다


@TransactionalEventListener
@Async
public void receiveEvent(EntryProcessEvent event) {
Copy link
Member

Choose a reason for hiding this comment

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

receiveEvent보다 의미있는 메서드명을 사용하면 좋을 것 같아요
이벤트 리스너가 여러개로 늘어나면 메서드명으로 해당 리스너가 어떤 일을 하는지 나타내는것이 필요할 것 같기도 하구요!
sendFcmNotification 과 같은 메서드가 있을 것 같네요

Copy link
Member Author

Choose a reason for hiding this comment

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

오 그렇네요 메서드명 감사합니다

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.

푸우 테스트도 꼼꼼하게 작성하셨네요!! 고생하셨습니다, 간단한 리뷰 몇개 남겼습니다.

this.memberFCMService = memberFCMService;
}

@TransactionalEventListener
Copy link
Collaborator

Choose a reason for hiding this comment

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

default after-commit이지만 명시적으로 해주는거 어떨까용

@Async
public void sendFcmNotification(EntryProcessEvent event) {
// TODO: channelId로 이벤트 구분 하는 로직 필요
List<Message> messages = createMessages(getMemberFCMToken(event.memberId()), null);
Copy link
Collaborator

Choose a reason for hiding this comment

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

푸우가 channelId에 관한 부분에 대한 이야기, null을 할당한 이유에 대한 부분을 구체적으로 작성해주셨는데

그래도 명시적으로 channelId를 할당 해주는 것이 좋지 않을까요? enum으로 할당해주면 될 것 같은데, 이 부분을 추가하는데 성능이나 시간이나 우리가 크게 리소스가 드는 부분은 아니니까요.

Comment on lines 39 to 43
private void validate(Member member, String fcmToken) {
if (member == null || fcmToken == null) {
throw new IllegalArgumentException("MemberFCM 은 허용되지 않은 null 값으로 생성할 수 없습니다.");
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

kotlin을 썼으면 이런일이 없었을텐데 ㅠㅠ

import org.springframework.transaction.event.TransactionalEventListener;

@Service
public class FCMNotificationFacade {
Copy link
Collaborator

Choose a reason for hiding this comment

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

이건 다들 생각이 다르실 것 같은데, Facade라는 명칭이(이미 쓰긴 했지만) 이해하기 애매한 부분이 분명히 있는 것 같아요.
(우리 같이 다 아는 상황이 아니라, 새롭게 저희 코드를 본다고 생각해볼때)

여기선 FCM을 찾아오는 MemberFcmService가 존재하니까, 전 FCMNotification이나 FCMNotificationService로 가는게 더 좋다고 생각하는데 다들 어떻게 생각하시나요?

Copy link
Member

Choose a reason for hiding this comment

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

저도 FCMNotificationService 좋은 것 같아요!

Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 클래스는 이벤트 리스너로 작동하고 있으니, Serivce라는 명칭보다는 다른 이름을 갖게 하는 것도 좋아보이네요.
또한 알람을 보내는 것은 비즈니스 로직에 관련된 부분이 아니니까 @Profile을 사용해서 프로덕션이나 데브 환경에서만 빈 등록을 하는 것도 좋아보이네요.

@@ -14,18 +18,34 @@
public class AuthService {
Copy link
Collaborator

@carsago carsago Sep 17, 2023

Choose a reason for hiding this comment

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

AuthService에서 수행되는 FCM 로직들을 MemberFCMService가 하는건 어떨까요?
AuthService 입장에선 코드가 조금이나마 간결해질 것 같아요.

Copy link
Member Author

Choose a reason for hiding this comment

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

.build();
}

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.

Suggested change
private void checkAllSuccess(BatchResponse batchResponse, Long memberid) {
private void checkAllSuccess(BatchResponse batchResponse, Long memberId) {

발견

Copy link
Member

Choose a reason for hiding this comment

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

옥상갈뻔했네요

Copy link
Collaborator

Choose a reason for hiding this comment

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

옥상 슈우웃

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.

애쉬랑 오리가 대부분 리뷰 남겨주셔서 크게 리뷰 남길 것은 없었네요.
구현체에 많이 의존하는 부분이 보여서, 해당 부분 개선해주시면 좋을 것 같아요.


@Entity
@Table(name = "member_fcm")
public class MemberFCM extends BaseTimeEntity {
Copy link
Collaborator

Choose a reason for hiding this comment

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

NoArgsConstruct가 필요할 듯 싶네요

private final Long id;

@NotNull
@ManyToOne
Copy link
Collaborator

Choose a reason for hiding this comment

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

fetch = FetchType.LAZY 속성이 누락된 것 같아용

Copy link
Member Author

Choose a reason for hiding this comment

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

import org.springframework.transaction.event.TransactionalEventListener;

@Service
public class FCMNotificationFacade {
Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 클래스는 이벤트 리스너로 작동하고 있으니, Serivce라는 명칭보다는 다른 이름을 갖게 하는 것도 좋아보이네요.
또한 알람을 보내는 것은 비즈니스 로직에 관련된 부분이 아니니까 @Profile을 사용해서 프로덕션이나 데브 환경에서만 빈 등록을 하는 것도 좋아보이네요.

Comment on lines 28 to 38
public LoginMemberDto login(UserInfo userInfo, String fcmToken) {
Optional<Member> loginMember = memberRepository.findBySocialIdAndSocialType(userInfo.socialId(), userInfo.socialType());
if (loginMember.isPresent()) {
Member member = loginMember.get();
enrollFcm(member, fcmToken);
return LoginMemberDto.isExists(member);
}
Member newMember = signUp(userInfo);
enrollFcm(newMember, fcmToken);
return LoginMemberDto.isNew(newMember);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Auth 도메인에 외부 API 구현체인 FCMRepository가 섞여있네요.
해당 부분은 이벤트를 사용해보는 것은 어떤가요?

Copy link
Member Author

Choose a reason for hiding this comment

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

Comment on lines 1 to 16
create table if not exists member_fcm
(
id bigint not null auto_increment,
created_at datetime(6),
updated_at datetime(6),
member_id bigint,
fcm_token varchar(255),
primary key (id)
) engine innodb
default charset = utf8mb4
collate = utf8mb4_0900_ai_ci;

alter table member_fcm
add constraint fk_member_fcm__member
foreign key (member_id)
references member (id);
Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 이슈 때문에 버전을 V202309180138 이렇게 사용하기도 한다네요

Comment on lines 11 to 13
@MockBean
FirebaseMessaging firebaseMessaging;

Copy link
Collaborator

Choose a reason for hiding this comment

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

DIP를 지켜야 할 것 같네요

Copy link
Member Author

Choose a reason for hiding this comment

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

Profile 로 Test 환경에서 보이지 않도록 했습니다 !!

Copy link
Member Author

@BGuga BGuga Sep 20, 2023

Choose a reason for hiding this comment

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

Profile 설정으로 테스트 환경에서 상관쓰지 않도록 변경했습니다 !!

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.

수고많으셨습니다 푸우 🫡

}

@Transactional(readOnly = true)
public MemberFCMsResponse findMemberFCM(Long memberId) {
List<MemberFCM> memberFCM = memberFCMRepository.findByMemberId(memberId);
if (memberFCM.size() < LEAST_MEMBER_FCM) {
logger.error("member {} FCM 코드가 발급되지 않았습니다.", memberId);
log.error("member {} FCM 코드가 발급되지 않았습니다.", memberId);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
log.error("member {} 의 FCM 코드가 발급되지 않았습니다.", memberId);
log.error("member {} 의 FCM 토큰이 발급되지 않았습니다.", memberId);

사소한건데 이거 어떤가요 ㅋㅋㅋ

Comment on lines +59 to +60
FAIL_SEND_FCM_MESSAGE("FCM Message 전송에 실패했습니다."),
FCM_NOT_FOUND("유효하지 않은 MemberFCM 이 감지 되었습니다.");
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
FAIL_SEND_FCM_MESSAGE("FCM Message 전송에 실패했습니다."),
FCM_NOT_FOUND("유효하지 않은 MemberFCM 이 감지 되었습니다.");
FAIL_SEND_FCM_MESSAGE("FCM Message 전송에 실패했습니다."),
FCM_NOT_FOUND("유효하지 않은 MemberFCM 이 감지 되었습니다."),
;

@Profile({"dev", "prod"})
public class FCMNotificationEventListener {

private static final Logger logger = LoggerFactory.getLogger(FCMNotificationEventListener.class);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
private static final Logger logger = LoggerFactory.getLogger(FCMNotificationEventListener.class);
private static final Logger log = LoggerFactory.getLogger(FCMNotificationEventListener.class);

아래 코드와 통일하면 좋을 것 같아요!

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.

고생하셨습니다!

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 0a1f237 into dev Sep 26, 2023
3 checks passed
@BGuga BGuga deleted the feat/#444 branch September 26, 2023 10:13
BGuga added a commit that referenced this pull request Oct 17, 2023
* feat: FCMConfig 생성

* chore: FCMConfig 패키지 이동

* feat: MemberFCM 생성

* feat: MemberFCMService 생성

* feat: NotificationFacade 생성

* feat: 로그인 시 fcm 을 등록한다.

* feat: 입장 처리 시 EntryProcessEvent 를 발행한다.

* feat: 유저 탈퇴시 유저의 FCM 을 모두 삭제한다.

* feat: 테스트 환경에서 FirebaseMessaging 을 MockBean 으로 등록한다

* chore: 테스트 컨벤션 적용

* chore: Notification -> FCMNotificationFacade 네이밍 변견

* feat: flyway 추가

* chore: 마지막 줄 개행 추가

* feat: submodule 업데이트

* refactor: 메서드 네이밍, 메서드 순서, 파라미터 순서 변경

* refactor: fcm bean 을 테스트에서 제외

* feat: EventListener phase 명시

* chore: FCMEventListener 네이밍 변경

* feat: MemberFCM 의 Member 의존성 제거

* chore: EntryProcessEvent 패키지 분리

* refactor: AuthService 가 MemberFCM 을 의존하지 않도록 변경

* feat: MemberFCM 빈 생성자 추가

* chore: flyway version 변경

* feat: FCMChannel 을 Enum 으로 관리

* chore: 메서드 접근자 및 네이밍 변경, log 메세지 변경

* feat: local prod, dev 환경에서만 FCM Bean 들이 생성되도록 변경

* refactor: eventListen 로직을 비동기적으로 처리한다

* refactor: LoginService 와 MemberFCMService 를 분리한다

* chore: 파라미터 네이밍 변경

* chore: logger -> log 네이밍 변경

* chore: log 메시지 변경

* chore: flyway 버전 변경
BGuga added a commit that referenced this pull request Oct 17, 2023
* feat: FCMConfig 생성

* chore: FCMConfig 패키지 이동

* feat: MemberFCM 생성

* feat: MemberFCMService 생성

* feat: NotificationFacade 생성

* feat: 로그인 시 fcm 을 등록한다.

* feat: 입장 처리 시 EntryProcessEvent 를 발행한다.

* feat: 유저 탈퇴시 유저의 FCM 을 모두 삭제한다.

* feat: 테스트 환경에서 FirebaseMessaging 을 MockBean 으로 등록한다

* chore: 테스트 컨벤션 적용

* chore: Notification -> FCMNotificationFacade 네이밍 변견

* feat: flyway 추가

* chore: 마지막 줄 개행 추가

* feat: submodule 업데이트

* refactor: 메서드 네이밍, 메서드 순서, 파라미터 순서 변경

* refactor: fcm bean 을 테스트에서 제외

* feat: EventListener phase 명시

* chore: FCMEventListener 네이밍 변경

* feat: MemberFCM 의 Member 의존성 제거

* chore: EntryProcessEvent 패키지 분리

* refactor: AuthService 가 MemberFCM 을 의존하지 않도록 변경

* feat: MemberFCM 빈 생성자 추가

* chore: flyway version 변경

* feat: FCMChannel 을 Enum 으로 관리

* chore: 메서드 접근자 및 네이밍 변경, log 메세지 변경

* feat: local prod, dev 환경에서만 FCM Bean 들이 생성되도록 변경

* refactor: eventListen 로직을 비동기적으로 처리한다

* refactor: LoginService 와 MemberFCMService 를 분리한다

* chore: 파라미터 네이밍 변경

* chore: logger -> log 네이밍 변경

* chore: log 메시지 변경

* chore: flyway 버전 변경
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BE] 스태프 인증 처리시 FCM 을 통해 유저 핸드폰에 입장 처리 완료 메시지를 보낸다
4 participants