그린체리 프로젝트를 바탕으로 알림서비스에 대한 구조를 간단하게 설명하자면,
프론트 단에서 처음 로그인을 할 경우,
1. 알림 허용에 대한 권한에 대해 묻는다.
2. 허용을 눌렀을 경우 각 아이디당 플랫폼에 해당한 유니크한 토큰을 발급하여 회원정보와 함께 DB에 저장한다.
프론트 단에서 알림관련 API 호출할 경우,
1. 백엔드 단에서 알림에 관련된 API가 호출되면서 해당 내용에 대한 알림을 회원에게 보낸다.
각 프론트, 백엔드에서 FCM이 무슨 역할을 하는지 이해하는 게 중요하다
프론트에서 FCM은 알림 허용 권한, 토큰 발급의 역할을 하는 대신,
백엔드에서 FCM은 알림을 프론트로 보내는 역할을 한다
실질적인 FCM은 백엔드에서 사용된다고 볼 수 있다
해당 프로젝트에선 백엔드 서버인 Java에서 알림을 구현했지만, Node.js,Python 등에서도 구현이 가능하다고 한다.
프로젝트에서 FCM을 사용한 이유는 간단하다
1. 플랫폼 종속성 없이 push 메시지 전송 가능
2. 사용자 기기의 배터리 및 네트워크 리소스 절약
3. 백그라운드를 통한 푸시 알림 기능
1. 플랫폼 종속성 없이 push 메시지 전송 가능
iOS,Android, Web 각 플랫폼에서 push 메시지를 보내려면 각 플랫폼별로 개발해야 하는 불편함이 있는데,
FCM을 이용하면 플랫폼에 종속되지 않고 push 메시지를 전송할 수 있다
2. 사용자 기기의 배터리 및 네트워크 리소스 절약
서버를 경유해서 실시간 push 메시지를 받으려면 사용자는 항상 서버에 접속해야하는데,
이는 사용자 기기의 배터리 및 네트워크 리소스를 크게 낭비한다
클라우드 메시징 서비스를 사용하면
사용자는 낮은 배터리와 네트워크의 사용만으로도 메시지를 실시간으로 송수신 처리를 할 수 있다
이와 같은 이유로 대부분의 어플리케이션 서비스들은 클라우드 메시징 서버를 경유해서,
실시간으로 유저들에게 메시지를 전송해주고 있다고 한다
3. 백그라운드를 통한 푸시 알림 기능
PWA의 Service Worker를 활용하여 웹 페이지와는 별개로 백그라운드 동기화나 푸시 알림 기능을 구현하기 위해 선택했다
구현 단계 정리
[Frontend] React에서 PWA 구현 단계
- PWA Manifest 설정하기 PWA Manifest를 설정하기 위해서는 public/manifest.json 파일을 생성합니다. 이 파일에서는 앱의 이름, 아이콘, 시작 URL 등을 정의할 수 있다
- Service Worker 구현하기 Service Worker는 public/service-worker.js 파일에서 구현할 수 있습니다. 이 파일에서는 Service Worker의 라이프사이클 이벤트를 처리하고, 오프라인 캐싱 등의 기능을 구현할 수 있다
- Push Notification을 위한 FCM 설정하기 Firebase Cloud Messaging(FCM)을 이용하여 Push Notification을 구현할 수 있다 이를 위해서는 Firebase 프로젝트를 생성하고, FCM을 설정해야 합니다. React에서는 firebase 모듈을 이용하여 FCM SDK를 사용할 수 있다
- 알림 목록을 가져올 API 구현하기 알림 목록을 가져오기 위한 API를 구현해야 한다. 이를 위해서는 Spring Boot Java 백엔드에서 알림을 저장하고, 필요한 API를 구현한다.
- React 프론트엔드에서 API 호출하기 React에서는 axios 또는 fetch 등의 라이브러리를 이용하여 API를 호출할 수 있다. 필요한 API를 호출하여 알림 목록을 가져와야 한다.
- 알림을 표시하는 컴포넌트 구현하기 알림 목록을 가져온 후에는 알림을 표시하는 컴포넌트를 구현해야 한다. 이를 위해서는 React에서 Notification API를 이용할 수 있다.
- PWA를 등록하기 PWA를 등록하기 위해서는 index.js 파일에서 serviceWorkerRegistration.register()를 호출해야 한다.
PWA를 사용하기 위해서는 Service Worker를 등록해야 합니다. 이를 위해 아래와 같이 코드를 추가할 수 있습니다.
import { initializeApp } from 'firebase/app';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';
const firebaseConfig = {
// Firebase 설정 정보
};
// Firebase 초기화
const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);
// Service Worker 등록
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
try {
const registration = await navigator.serviceWorker.register('/firebase-messaging-sw.js');
messaging.useServiceWorker(registration);
console.log('ServiceWorker registration successful with scope: ', registration.scope);
} catch (err) {
console.log('ServiceWorker registration failed: ', err);
}
});
}
// 알림 권한 요청 및 토큰 발급
async function requestPermission() {
console.log('권한 요청 중...');
const permission = await Notification.requestPermission();
if (permission === 'denied') {
console.log('알림 권한 허용 안됨');
return;
}
console.log('알림 권한이 허용됨');
const token = await getToken(messaging, {
vapidKey: 'BBuoQiK6Hci6-fWBqgcIAn-a8Nzc7kF1XVpkCKfHINcvckb-u3sz8eSrsbtns2WjrXZ9bxs7j0DCsNtkNIiqjHc',
});
if (token) console.log('token: ', token);
else console.log('Can not get Token');
// 알림 수신 처리
onMessage(messaging, (payload) => {
console.log('메시지가 도착했습니다.', payload);
// ...
});
}
requestPermission();
위 코드에서 /firebase-messaging-sw.js는 Service Worker 파일이 위치한 경로를 의미한다. 이 경로는 실제 프로젝트에서 사용하는 경로에 맞게 변경해주어야 한다. 또한, vapidKey는 Web Push에서 사용되는 Public Key 값으로 변경해야 한다.
[Backend] Spring Boot Java 에서 알림을 구현 단계
- FCM 설정하기 Firebase Console에서 프로젝트를 생성하고, FCM을 설정한다.
- Firebase Admin SDK 연동하기 Firebase Admin SDK를 이용하여 FCM을 사용할 수 있다. 이를 위해서는 Firebase Console에서 서비스 계정을 생성하고, 해당 계정의 인증 정보를 이용하여 Firebase Admin SDK를 초기화한다.
- FCM API 구현하기 Spring Boot Java 백엔드에서는 FCM API를 구현하여 Push Notification을 보낸다. 이를 위해서는 Firebase Admin SDK의 Messaging 클래스를 이용한다.
- 알림 목록 API 구현하기 알림 목록을 조회하고 관리하기 위해서는 백엔드에서 알림 관련 데이터를 저장하고, 필요한 API를 구현해야 한다. 예를 들어, 알림 목록을 조회하는 API를 구현하면, 프론트엔드에서 해당 API를 호출하여 알림 목록을 가져올 수 있다. 이때 백엔드에서는 데이터베이스를 이용하여 알림 정보를 저장하고, RESTful API를 구현하여 프론트엔드와 통신합니다. 또한, 알림을 클릭하면 해당 알림으로 이동할 수 있는 링크를 제공하기 위한 API도 구현할 수 있다. 이렇게 구현된 API를 이용하여, 사용자가 알림을 클릭하면 백엔드에서 해당 알림에 대한 처리를 수행하고, 필요한 화면으로 이동시키는 것이 가능한다.
구현 단계 자세히 보기
1. FCM 설정하기
파이어베이스 프로젝트 생성
- Firebase에 로그인하고 프로젝트를 연다
- 개요 페이지에서 앱 추가를 클릭한다
- 웹 앱에 Firebase 추가를 선택한다
- 스니펫을 복사하여 애플리케이션 HTML에 추가한다
💡 SDK 설정 및 구성 (Firebase SDK snippet) 을 잘 확인해야 한다
프로젝트 설정에서 일반탭에서 생성한 앱에 대한 정보를 확인이 가능하며, FCM은 클라우드 메시징 탭에서 확인 가능하다.
비밀 키 파일 생성
생성한 프로젝트 페이지 > 설정 > 서비스 계정 항목
프로젝트로 생성된 비밀키를 이동
원래 깃허브와 같이 공개된 장소에 이 파일을 같이 올리는 것은 안전하지 않다고 한다
이번 프로젝트에서는 json 파일로 생성된 비밀 키를 resources 디렉토리에 저장했다
resources/firebase/greencherry-notice.json
{
"type": "service_account",
"project_id": "greencherry-notice",
"private_key_id": "",
"private_key": "",
"client_email": "",
"client_id": "",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-qjueq%40greencherry-notice.iam.gserviceaccount.com"
}
Dependency 설정
build.gradle
implementation 'com.google.firebase:firebase-admin:9.1.1'
application.yml
firebase:
path: firebase/greencherry-notice.json
FCM 초기화
어플리케이션이 시작될 때 Firebase 프로젝트에 앱을 등록해줘야 한다.
(두 번 등록 되면 에러가 나므로 시작할 때마다 초기화 해준다)
commons/NoticeInitializer.java
@Slf4j
@Component
public class NoticeInitializer {
@Value("${firebase.path}")
private String path;
@PostConstruct
public void init(){
ClassPathResource resource = new ClassPathResource(path);
try(InputStream is = resource.getInputStream()) {
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(is))
.build();
if(FirebaseApp.getApps().isEmpty()){
FirebaseApp.initializeApp(options);
log.info("Firebase application init");
}
} catch (IOException e) {
e.printStackTrace();
log.error(e.getMessage());
}
}
}
3. FCM API 구현하기 (메세지 보내기)
메세지를 보낼 때 필요한 요소는 2가지이다
1. 누구한테 보낼지
토큰과 토픽 방식으로 보낼 수 있는데, 토큰을 사용했다
2. 어떤 정보를 보낼지
아래와 같이 Message를 보내는 별도의 서비스를 만들었다
NotificationRequest에는 받을 상대의 토큰값, 푸시될 알림 메세지와 제목을 가지고 있고
사용하진 않지만, 이미지도 지정해서 넣어줄 수 있다
service/NoticeService
public void sendNotice(List<String> tokens){
for (String token : tokens) {
Message message = Message.builder()
.setToken(token)
.putData("title", "제목")
.putData("body", "내용")
.setWebpushConfig(WebpushConfig.builder().putHeader("ttl", "1000")
.setNotification(new WebpushNotification("title", "body"))
.build())
.build();
FirebaseMessaging.getInstance().sendAsync(message);
}
}
더 자세한 코드를 확인하실 분은 아래 링크 참고 부탁드립니다
https://github.com/tandamzi/GreenCherry
참고
Web Push | React + FCM 구현하기 (feat. pwa, service worker)
웹에서도 네이티브 앱처럼 푸시 알람을 받을 수 있습니다. 웹의 사용성을 네이티브 앱처럼 개선하기 위해서 나온 기술인 PWA(Progressive Web Application)을 활용하면 가능합니다.PWA는 Progressive Web Applica
velog.io
FCM, Spring Boot를 사용하여 웹 푸시 기능 구현하기
Firebase firebase Firebase는 웹과 모바일 개발에 필요한 기능을 제공하는 BaaS(BackEnd as a Service) 이다. 백엔드 서버의 인프라들을 제공해주고 많은 기능들을 지원한다. 머신러닝 사용자 인증 파일 저장
velog.io
📮개인 공부를 위한 공간으로 틀린 부분이 있을 수도 있습니다.📮
문제점 및 수정 사항이 있을 시, 언제든지 댓글로 피드백 주시기 바랍니다.
'TIL' 카테고리의 다른 글
Redis ? (0) | 2023.05.26 |
---|---|
FCM(Firebase Cloud Messaging) (0) | 2023.05.26 |
[JPA] OSIV와 성능 최적화 (0) | 2023.03.22 |
[JPA] API 개발 고급 정리 (1) | 2023.03.21 |
[JPA] 페이징과 한계돌파 (0) | 2023.03.20 |