[캡스톤] 기능 개발 - 알림 기능 (FCM, Firebase Cloud Messaging)

이신행·2024년 6월 24일

capstone

목록 보기
9/15
post-thumbnail

FCM 사용 배경

알림 기능을 구현하는 데는 방법이 여러 가지가 있습니다.
웹 소켓을 이용하는 방식, 스프링의 SSE(Server-Sent Event)를 이용하는 방식, FCM을 이용하는 방식 등이 있을 것입니다.
그중에서 FCM을 이용한 이유는 다음과 같습니다.

  1. 우리 서비스의 프론트가 안드로이드 앱이다.
  2. 무료로 사용 가능하다.
  3. 사용하기 쉽다.

FCM 이란?

Firebase는 구글에서 제공하는 백엔드 서비스 플랫폼(BaaS)으로 서버의 많은 기능을 제공합니다.
Firebase에서 제공하는 서비스 중 FCM은 메시지 전송 서비스로 푸시 알림을 보낼 때 사용할 수 있습니다.
FCM에서는 각 기기별로 고유의 FCM 토큰을 생성합니다.
그래서 FCM 토큰과 사용자를 미리 매핑해두고, 특정 사용자에게 알림을 전송할 때, 매핑한 토큰을 사용하면 됩니다.

사용법

앱 등록

FCM을 사용하기 위해서 먼저 앱을 등록해야 합니다.
구글에 fcm을 검색하고 들어갑니다.
우상단의 go to console을 누릅니다.

그리고 프로젝트를 만들어 줍니다.
프로젝트 만들기를 누르고 이름을 입력합니다.

구글 애널리스틱을 사용할지 말지 눌러주면 프로젝트가 생성됩니다.

위와 같이 프로젝트가 생성되었다는 화면이 뜹니다.
계속을 누르면 다음 화면이 뜹니다.

빨간 밑줄을 그은 부분에서 차례대로 iOS, 안드로이드, 웹 앱을 추가할 수 있습니다.
안드로이드를 눌러 저희의 안드로이드 앱을 추가해 보겠습니다.
패키지 명은 안드로이드 스튜디오에서 개발 시에 생성한 패키지로 입력합니다.
패키지 명만 필수니까 나머지는 넣지 않고, 앱 등록을 누르겠습니다.
안드로이드 추가부터는 백엔드가 아닌 프론트와의 협업이 필요합니다.
[백엔드 작업] 전까지는 모두 안드로이드 쪽에서 수행하는 일입니다.

다운로드할 json 파일이 나옵니다.
화면에 보이는 위치에 json 파일을 넣어주고 다음으로 넘어갑니다.

쭉 입력해야 하는 의존성 코드들이 나옵니다.
가이드가 잘 나와있으니 따라서 입력하시면 됩니다.
이제 완료를 누르고 다시 콘솔로 돌아가면 앱이 등록된 것을 알 수 있습니다.

백엔드 작업

가독성을 위해 일부 코드를 수정, 삭제했습니다. 코드 전문은 아래의 깃허브에서 확인하실 수 있습니다.

json 파일 받기

먼저 앞서 받은 json 파일을 .gitignore로 설정합니다.
저는 firebase 폴더를 만들어서 해당 폴더 자체를 깃에 올리지 않았습니다.

/src/main/resources/firebase/

이제 앞서 받은 json 파일을 resource/firebase 폴더 아래 둡니다.

의존성 추가

dependencies {
	implementation 'com.google.firebase:firebase-admin:9.2.0'
}

Configuration 파일

FCM 전송에 사용할 FCMConfig 설정 파일을 만들어줍니다.

@Configuration
public class FCMConfig {
    @Bean
    FirebaseMessaging firebaseMessaging() throws IOException {
        String firebaseConfigPath = "firebase/아까_넣은_파일_이름.json";
        ClassPathResource resource = new ClassPathResource(firebaseConfigPath);

        InputStream refreshToken = resource.getInputStream();

        FirebaseApp firebaseApp = null;
        List<FirebaseApp> firebaseAppList = FirebaseApp.getApps();

        if(! firebaseAppList.isEmpty()) {
            for (FirebaseApp app : firebaseAppList) {
                if(app.getName().equals(FirebaseApp.DEFAULT_APP_NAME)) {
                    firebaseApp = app;
                }
            }
        } else {
            FirebaseOptions options = FirebaseOptions.builder()
                    .setCredentials(GoogleCredentials.fromStream(refreshToken))
                    .build();

            firebaseApp = FirebaseApp.initializeApp(options);
        }
        return FirebaseMessaging.getInstance(firebaseApp);
    }
}

FCM 전송 Service 계층

@Service
@RequiredArgsConstructor
public class FCMService {
	// 외부 라이브러리인 FirebaseMessaging에서 알림을 전송해 줌
    private final FirebaseMessaging firebaseMessaging;
    private final MemberRepository memberRepository;

    public String SendNotificationByToken(FCMNotificationDTO dto) {
        Optional<Member> foundMember = memberRepository.findById(dto.getReceiverId());

        Notification notification = Notification.builder()
                .setTitle(dto.title)
                .setBody(dto.body)
                .build();

        Message message = Message.builder()
                .setToken(foundMember.get().getFcmToken())
                .setNotification(notification)
                .build();

        try {
            firebaseMessaging.send(message);
            return "성공";
        } catch (FirebaseMessagingException e) {
            return null;
        }
    }
}

호출

이제 비즈니스 로직에 따라 알맞은 정보를 dto에 넣어서 해당 메서드를 호출해 주면 알림이 전송됩니다.
호출 비즈니스 로직 부분까지 다루면 너무 길어질 것 같아 다음 포스트에서 다루도록 하겠습니다.
다음 포스트를 보지 않더라도 각자 원하는 조건을 설정하면 알림 전송을 해볼 수 있습니다.

마무리

FCM을 이용해서 알림 기능을 구현해 보았습니다.
프론트와의 협업이 필요한 부분이라 소통 능력이 필요했습니다.

코드 깃허브

https://github.com/LeeShinHaeng/safeGuard

profile
언제나 Response 하는 Ability가 있는 서버를 만드는, Responsibility 있는 개발자가 되자

0개의 댓글