java spring pwa fcm web push 구현
구글 FCM 프로젝트 등록은 https://yeolco.tistory.com/85 를 참고하세요.
안드로이드 기준으로 작성되어있으니 프로젝트 생성까지만 따라하시고 오세요.
0. maifest.json
PWA 프로젝트 기준으로 작성되었기 때문에 mainfest.json내에
{
"gcm_sender_id": "103953800507"
}
를 추가해줍니다.
아이디는 위 아이디 그대로 사용하시면 됩니다.
(자신의 프로젝트의 sender id를 작성하면 오류발생합니다.)
1. 스크립트 영역(프론트)
<script src="https://www.gstatic.com/firebasejs/6.6.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.10.1/firebase-messaging.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaSyAnAp-nWTe4_N8piai73nfsl50lotYneu4",
authDomain: "cms-test-4f739.firebaseapp.com",
databaseURL: "https://cms-test-4f739.firebaseio.com",
projectId: "cms-test-4f739",
storageBucket: "",
messagingSenderId: "1095403590845",
appId: "1:1095403590845:web:b675f1753fc15ca0ab93d4"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
console.log("FCM INIT DONE");
</script>
프로젝트 설정 부분에서
이 부분을 그대로 복사한 후
푸시 메세지 사용을 위해
<script src="https://www.gstatic.com/firebasejs/5.10.1/firebase-messaging.js"></script>
를 추가해줍니다.
프론트 단(js)에서 적절한 위치(이벤트)에 토큰을 등록해줍니다.
const messaging = firebase.messaging();
messaging.usePublicVapidKey(applicationServerPublicKey);
Notification.requestPermission().then((permission) => {
if (permission === 'granted') {
console.log('Notification permission granted.');
// TODO(developer): Retrieve an Instance ID token for use with FCM.
messaging.getToken().then((currentToken) => {
if (currentToken) {
var data = {
'token' : currentToken
};
$.ajax({
url: '/insertPushToken.do',
type: 'POST',
data: data,
success: function(data) {
console.log('RESULT', data);
},
error: function(err) {
console.log('ERROR', err);
}
});
} else {
console.log('No Instance ID token available. Request permission to generate one.');
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
showToken('Error retrieving Instance ID token. ', err);
setTokenSentToServer(false);
});
}
else {
console.log('Unable to get permission to notify.');
}
});
1) applicationServerPublicKey는 FCM 콘솔에서 키 쌍 생성해서 넣어줍니다.
2) $.ajax 부분은 db에 토큰을 저장하는 부분입니다.
개인적으로 구현해서 사용하시면 됩니다. (혹시 필요하시면 댓글)
2. 자바(백엔드) 영역
// 푸시보내기 TEST
String FCM_URL = "https://fcm.googleapis.com/fcm/send";
String server_key = "AAAA_wskVL0:APA91bEd...............................kropWYS";
String tokenId = "e6vkJHnCd6s:.................................U_nYts_01-XNhzV";
String result = "";
URL url = new URL(FCM_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "key=" + server_key);
conn.setRequestProperty("Content-Type", "application/json");
JSONObject json = new JSONObject();
try {
json.put("to", tokenId.trim());
JSONObject data = new JSONObject();
data.put("url", "https://test.com");
data.put("icon", "test.png");
json.put("data", data);
JSONObject info = new JSONObject();
info.put("title", "푸시 테스트 중입니당");
info.put("body", "삐뽀삐뽀");
json.put("notification", info);
} catch (JSONException e1) {
e1.printStackTrace();
}
try {
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(json.toString());
wr.flush();
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
result = "succcess";
} catch (Exception e) {
e.printStackTrace();
result = "failure";
}
System.out.println("GCM Notification is sent successfully : " + result);
1. FCM_URL : 고정값입니다.
2. server_key : 동그라미 친 부분입니다.
3. tokenId : 위에 프론트단에서 ajax로 디비에 넣은 토큰입니다.
저도 귀찮아서 그냥 하드코딩했어요 (이 부분은 디비에서 불러오면 됩니다.)
아 참고로 지금 단일 푸시 테스트 코드입니다.
여러명에게 보내는건 추후에 구현하고 올려드릴게요!
10/1 수정-----------------------------------------------------------------------------------
** 푸시 여러명에게 한번에 보내기
실제 프로젝트에서 수백~수천명에게 푸시를 보내야 하기 때문에
위 코드를 반복문으로 활용했을 경우 해당 코드에서 반복문을 돌면서(동기) 오랜시간 로딩이 걸린다.
fcm에서 여러명에게 푸시를 보내는 기능을 지원한다.
https://firebase.google.com/docs/cloud-messaging/http-server-ref
위 링크에서 다운스트림 json 부분을 확인한다.
위 단일 전송 코드에서 json.put("to", 토큰) 부분을 주석처리하고
아래와 같이 "registration_ids"를 추가한다.
=> json.put("registration_ids", tokens);
tokens는 배열(List)로 구성되어있다.
토큰들이 담긴 배열을 추가하면 된다.
처리 속도는 단일 메시지 보단 느리지만 300명 정도 테스트했을때 1초 이내로 실행되는것을 확인했다.
----------------------------------------------------------------------------------------------
4. Service worker.js (서비스워커)
firebase push 사용시 서비스워커 js 파일을 만들어야합니다.
index와 같은 루트단에 firebase-messaging-sw.js 파일 생성하고 아래와 같이 작성합니다.
(토씨하나도 틀리면 오류나요)
var push_url;
// Functional: PUSH
self.addEventListener('push', event => {
var push_data = eval("(" + event.data.text() + ")");
push_url = push_data.data.url;
const title = push_data.notification.title;
const options = {
body: push_data.notification.body,
icon: push_data.data.icon
};
event.waitUntil(self.registration.showNotification(title, options));
});
// Push Notification Click
self.addEventListener('notificationclick', function(event) {
console.log('Notification click Received.', push_url);
event.notification.close();
if(push_url != null) {
event.waitUntil(
clients.openWindow(push_url)
);
}
});
1) self.addEventListener('push', event => : 푸시 받는 부분입니다.
서버에서 푸시를 정상적으로 보내도 여기서 오류나면 못받습니다.
2) self.addEventListener('notificationclick', function(event) : 푸시 notification 눌렀을때 처리할 이벤트입니다.
작동화면
'Java' 카테고리의 다른 글
facebook graph api로 게시글 가져오기 (1) | 2019.09.23 |
---|---|
구글, 파파고 번역 API 성능 비교 (1) | 2019.09.18 |
google translate api v3 사용법 (1) | 2019.09.16 |
Object 클래스에 대해 (0) | 2018.11.04 |
자바 표준 입력 클래스 Scanner 사용법 (1) | 2018.11.04 |
자바 상속 (0) | 2018.10.17 |
자바 싱글톤 클래스(Singleton class) (3) | 2018.10.16 |
자바 Wrapper Class (0) | 2018.10.15 |