티스토리 뷰

Java

java spring pwa fcm web push 구현

열코 2019. 9. 10. 18:01
반응형

 

구글 FCM 프로젝트 등록은 https://yeolco.tistory.com/85 를 참고하세요.

안드로이드 기준으로 작성되어있으니 프로젝트 생성까지만 따라하시고 오세요.

 

0. maifest.json

PWA 프로젝트 기준으로 작성되었기 때문에 mainfest.json내에

{

"gcm_sender_id": "[id]"

}

를 추가해줍니다.

아이디는 위 아이디 그대로 사용하시면 됩니다.

(자신의 프로젝트의 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: "[apiKey]",

authDomain: "[ authDomain ]",

databaseURL: "[ databaseURL ]",

projectId: "[ projectId ]",

storageBucket: "",

messagingSenderId: "[ messagingSenderId ]",

appId: "[ appId ]"

};

// 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 눌렀을때 처리할 이벤트입니다.

 

작동화면

 

 

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/08   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
글 보관함
반응형