±âŸ(framework)
2018.03.21 / 01:56

Firebase Web äÆÃ¾Û ¸¸µé±â - Cloud Messaging°ú FunctionsÀ» ÀÌ¿ëÇÑ Çª½Ã¸Þ¼¼Áö ±â´É - Service worker

ÈÞ°í
Ãßõ ¼ö 205
FCM ¼ö½ÅÀº ¾ÛÀÌ ±¸µ¿µÇ°í ÀÖÀ» ¶§ ¼ö½ÅÇÏ´Â Æ÷±×¶ó¿îµå·Î ¼ö½ÅÇÏ´Â ¹æ¹ý°ú ¾ÛÀÌ ±¸µ¿µÇ°íÀÖÁö ¾ÊÀ» ¶§ ¹é±×¶ó¿îµå·Î ¼ö½ÅÇÏ´Â ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù.  Á¢¼ÓÇÏÁö ¾ÊÀº À¯Àúµé¿¡°Ô¸¸ Ǫ½Ã¸¦ º¸³»·Á°í Çϱ⠶§¹®¿¡ ¹é±×¶ó¿îµå¸¸ ÀÛ¼ºÇÒ °èȹÀÔ´Ï´Ù. 

Æ÷±×¶ó¿îµå·Î ¼ö½ÅÇÏ´Â ¹æ¹ýµµ Àá½Ã ¼Ò°³ÇÕ´Ï´Ù. ¾Æ·¡´Â Æ÷±×¶ó¿îµå·Î ¼ö½ÅÇÏ´Â ÄÚµåÀÔ´Ï´Ù. Firebase MessagingÀ» ¼³Á¤ÇÒ¶§ ±ÇÇÑÀ» ȹµæÇϸ鼭 requestPermission ¸Þ¼Òµå¸¦ ½ÇÇàÇߴµ¥,  ÀÌ ¸Þ¼Òµå ÀÌÈÄ¿¡ Àû´çÇÑ À§Ä¡¿¡¼­ ½ÇÇàÇÏ¸é µË´Ï´Ù.

firebase.messaging().onMessage(function(payload) {
    var options = {
        body : payload.notification.body
        icon : payload.notification.icon
    }
    var notification new Notification(payload.notification.titleoptions);
    notification.onclickfunction(event){
        event.preventDefault();
        ... (»ý·«) ¾Ë¸² Ŭ¸¯½Ã ÄÚµå ÀÛ¼º
    }
});




ÀÌÁ¦ ¹é±×¶ó¿îµå ¼ö½ÅÇÏ´Â °ÍÀ» ÀÛ¼ºÇÏ°Ú½À´Ï´Ù. ¸ÕÀú ÇÁ·ÎÁ§Æ®³»¿¡ public Æú´õ ¾Æ·¡¿¡ manifest.json ÆÄÀÏÀ» Çϳª ¸¸µì´Ï´Ù. mainfiest.json ÆÄÀÏÀº À¥¿¡ ºÎ°¡±â´ÉÀ» ¸í½ÃÇÏ´Â ÆÄÀÏÀÔ´Ï´Ù. ¿ÀÇÁ¶óÀÎ À¥¾ÛÀ» ¸¸µé ¶§ ÁÖ·Î »ç¿ëµË´Ï´Ù. Firebase Messaging ¼ö½ÅÀ» À§ÇØ ¾Æ·¡ÀÇ Äڵ带 ÀÔ·ÂÇÕ´Ï´Ù.

{
"gcm_sender_id": "103953800507"
}
view rawmanifest.json hosted with ❤ by GitHub




'103953800507' À̶ó´Â ¼ýÀÚ´Â °íÁ¤°ªÀÔ´Ï´Ù. ÇÁ·ÎÁ§Æ®¸¶´Ù ´Þ¶óÁö°Å³ª ÇÏ´Â ¼ýÀÚ°¡ ¾Æ´Ï¸ç Firebase messaging¼­ºñ½º¸¦ ¼ö½ÅÇϱâ À§ÇÑ °íÁ¤°ªÀÔ´Ï´Ù.

manifest.jsonÆÄÀÏ ¿Ï¼º ÈÄ index.html ÆÄÀÏÀÇ head ÅÂ±× ¾È¿¡ ¾Æ·¡ÀÇ Äڵ带 ÀÔ·ÂÇØÁÖ¼¼¿ä.

<link rel="manifest" href="manifest.json"/>
view rawindex.html hosted with ❤ by GitHub




±×¸®°í Service worker¸¦ ÀÛ¼ºÇؾßÇÕ´Ï´Ù. Service worker ¶õ ¹«¾ùÀϱî¿ä? Service woker´Â ºê¶ó¿ìÀú°¡ ¹é±×¶ó¿îµå¿¡¼­ ½ÇÇàÇÏ´Â ½ºÅ©¸³Æ®ÀÔ´Ï´Ù. À¥ÆäÀÌÁö¿Í »óÈ£ÀÛ¿ëÇÏÁö ¾Ê´Â ±â´ÉµéÀ» ±¸ÇöÇÒ ¼ö ÀÖ½À´Ï´Ù. À¥ºê¶ó¿ìÀúÀÇ °³¹ßÀÚ µµ±¸¸¦ ¿­¾îº¸°Ú½À´Ï´Ù. ¾Æ·¡ÀÇ È­¸éÀº Å©·Ò°³¹ßÀÚ µµ±¸ÀÔ´Ï´Ù.
°³¹ßÀÚµµ±¸¿¡¼­ Application ÅÇ¿¡ Service Wokers Ç׸ñ¿¡ µé¾î°¡ Show all¿¡ üũ¸¦ Çغ¸¾Ò½À´Ï´Ù. ÀúÀÇ ºê¶ó¿ìÀú¿¡´Â ¿©·¯°¡Áö ¼­ºñ½º¿öÄ¿°¡ ÀÌ¹Ì ±¸µ¿ÀÌ µÇ°í ÀÖ±º¿ä. Å©·Ò ºê¶ó¿ìÀú¸¦ ½ÇÇàÇÏ°Ô µÇ¸é ÆäÀ̽ººÏ Ǫ½Ã°¡ ¿À´Â °æ¿ì°¡ Àִµ¥ ÀÌ´Â Service worker°¡ ¼öÇàÇÑ ÀÏÀÔ´Ï´Ù. 

¿¹Á¦·Î ÀÛ¼ºÇÏ°í Àִ äÆþۿ¡¼­µµ Ǫ½Ã¸¦ ¹Þ±â À§ÇØ Service wokrer¸¦ ÀÛ¼ºÇغ¸°Ú½À´Ï´Ù. ´Ù½Ã ÇÁ·ÎÁ§Æ®³» publicÆú´õ¿¡ 'firebase-messaging-sw.js' ÆÄÀϸíÀ¸·Î ÆÄÀÏÀ» Çϳª ¸¸µì´Ï´Ù. ±×¸®°í ¾Æ·¡ÀÇ Äڵ带 ÀÔ·ÂÇÕ´Ï´Ù.

importScripts('https://www.gstatic.com/firebasejs/4.6.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.6.1/firebase-messaging.js');
firebase.initializeApp({
'messagingSenderId': '151504463082' //ÀÌ°÷Àº ÀÚ½ÅÀÇ ÇÁ·ÎÁ§Æ® ¼³Á¤ => Ŭ¶ó¿ìµå ¸Þ¼¼Â¡ => ¹ß½ÅÀÚID¸¦ ±âÀÔ
});
const messaging = firebase.messaging();
self.addEventListener('push', function(event) {
const payload = event.data.json();
const title = payload.notification.title;
const options = {
body: payload.notification.body,
icon: payload.notification.icon,
data: payload.notification.click_action
};
event.waitUntil(self.registration.showNotification(title, options));
});
self.addEventListener('notificationclick', function(event) {
console.log(event.notification);
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data)
);
});





Äڵ带 »ìÆ캸°Ú½À´Ï´Ù.  importScripts´Â wokerÆÄÀÏ¿¡¼­ ¿ÜºÎ ¶óÀ̺귯¸®¸¦ ºÒ·¯¿Ã ¶§ »ç¿ëÇÕ´Ï´Ù.
initializeApp ¸Þ¼Òµå´Â FunctionsÄÚµå¿Í °°ÀÌ firebase¸¦ ÃʱâÈ­ ÇÕ´Ï´Ù. ¿©±â¼­´Â MessagingÀ» ÃʱâÈ­ ÇÕ´Ï´Ù. 

firebase.initializeApp({
    'messagingSenderId''¹ß½ÅÀÚID' //ÀÌ°÷Àº ÀÚ½ÅÀÇ ÇÁ·ÎÁ§Æ® ¼³Á¤ => Ŭ¶ó¿ìµå ¸Þ¼¼Â¡ => ¹ß½ÅÀÚID¸¦ ±âÀÔ
});

const messaging = firebase.messaging();

¹ß½ÅÀÚ ID¸¦ ÀÔ·ÂÇؾßÇϴµ¥ Firebase consoleÈ­¸é ÇÁ·ÎÁ§Æ® ¼³Á¤ Ŭ¶ó¿ìµå ¸Þ¼¼Â¡ ÅÇ¿¡¼­ È®ÀÎÇÒ ¼ö ÀÖ½À´Ï´Ù. Àú¿Í´Â ´Ù¸¦ °ÍÀ̹ǷΠȮÀÎ ÈÄ ÀÔ·ÂÇØÁÖ¼¼¿ä.





±× ´ÙÀ½ ÄÚµå´Â Ǫ½Ã¸Þ¼¼Áö¸¦ ¼ö½ÅÇßÀ» ¶§ µ¿ÀÛÀÔ´Ï´Ù. µ¥ÀÌÅ͸¦ ¼ö½ÅÇÏ°í ¾Ë¸² È­¸éÀ» ¶ç¿ì°Ô µË´Ï´Ù.
self.addEventListener('push'function(event) {
    const payload = event.data.json();
    const title payload.notification.title;
    const options = {
        bodypayload.notification.body,
        iconpayload.notification.icon,
        datapayload.notification.click_action
    };

    event.waitUntil(self.registration.showNotification(titleoptions));
});

´ÙÀ½ ÄÚµå´Â ¾Ë¸² È­¸éÀ» Ŭ¸¯ÇßÀ» ¶§ ÀÔ´Ï´Ù. ¼ö½ÅÇßÀ» ¶§ options °´Ã¼¿¡ ÇÒ´çÇÑ data °ª¿¡ ÇÒ´çµÈ URL·Î À̵¿ÇÏ°Ô µË´Ï´Ù. FunctionsÄڵ忡 payload click_action µ¥ÀÌÅÍ¿¡ `http://ÇÁ·ÎÁ§Æ®È£½ºÆÃÁÖ¼Ò=${roomId}µ¥ÀÌÅ͸¦ ÀÔ·ÂÇÏ¿´´Âµ¥ ÀÌ URL·Î À̵¿ÇÏ°Ô µÉ °ÍÀÔ´Ï´Ù. ±×¸®°í URL ÆĶó¹ÌÅÍ·Î ·Î±×ÀÎ ÀÌÈÄ¿¡ äÆùæÀ» ¿ÀÇÂÇÏ°Ô µË´Ï´Ù.
self.addEventListener('notificationclick'function(event) {
    event.notification.close();
    event.waitUntil(
        clients.openWindow(event.notification.data)
    );
});
Service worker ÄÚµå´Â ¿Ï¼ºµÇ¾ú°í, ±âº»ÀûÀ¸·Î mainfest.json À» ¸¸µé°í, firebase-messaging-sw.js ¸íĪÀ¸·Î Service workerÆÄÀÏÀ» ¸¸µé¸é À¥¾ÛÀÌ ±¸µ¿µÉ ¶§ ºê¶ó¿ìÀú¿¡ Service worker°¡ ¼³Ä¡°¡ µË´Ï´Ù. ÇÏÁö¸¸ °³ÀÎÀûÀÎ °æÇèÀ¸·Î ¼öÁ¤µÈ Äڵ尡 ¹Ý¿µÀÌ ÀßµÇÁö ¾Ê¾Æ ¸í½ÃÀûÀ¸·Î È­¸éÀÌ ·ÎµåµÉ ¶§¸¶´Ù Äڵ带 ÀÔ·ÂÇÏ°Ú½À´Ï´Ù. 

´Ù½Ã index.htmlÆÄÀÏÀ» ¿­¾î ¾Æ·¡ÀÇ Äڵ带 Ãß°¡ÇÕ´Ï´Ù.

<script>
/**
* Dom ·Îµù ÈÄ µ¿ÀÛ
*/
document.addEventListener('DOMContentLoaded', function() {
//...»ý·«
if(navigator.serviceWorker){
navigator.serviceWorker.register('/firebase-messaging-sw.js')
.then(function(reg){console.log('¼­ºñ½º¿öÄ¿ µî·Ï¼º°ø :', reg)})
.catch(function(error){console.log('¼­ºñ½º¿öÄ¿ µî·Ï½ÇÆÐ :', error)});
}
});
view rawindex.html hosted with ❤ by GitHub




¼ö½Å ÀÛ¾÷Àº ¿Ï·áµÇ¾ú½À´Ï´Ù. ÇÑ°¡Áö°¡ ³²¾Ò´Âµ¥, ¾Ë¸²À» Ŭ¸¯ÇÏ°í ·Î±×ÀÎ ½Ã¿¡ äÆùæÀ¸·Î ¹Ù·Î ÁøÀÔÇÏ´Â Äڵ带 ÀÛ¼ºÇÕ´Ï´Ù. ÄÚµå´Â loadRoomList ¸Þ¼Òµå¸¦ ÅëÇØ Ã¤ÆÃ¹æ ¸ñ·ÏÅÇÀ» ±×¸®´Â ¸Þ¼ÒµåÀÎ getRoomList ¸Þ¼Òµå¿¡ Äڵ带 Ãß°¡ÇÏ°Ú½À´Ï´Ù. 

<script>
/**
* loadRoomList ¿¡¼­ µ¥ÀÌÅ͸¦ ¹Þ¾Æ¿ÔÀ» ¶§
*/
FirebaseChat.prototype.getRoomList = function(snapshot){
var arrRoomListHtml = [];
var cbDisplayRoomList = function(data){
//...»ý·«
// äÆùæÀ» ·Îµå ÈÄ url¿¡ roomIdÆĶó¹ÌÅÍ°¡ ÀÖÀ¸¸é äÆùæÀ» Ŭ¸¯ÇÑ´Ù.
var paramData = FirebaseChat.getParam('roomId');
if(paramData && paramData.length > 0){
document.getElementById('liRoom' + paramData).click();
history.replaceState('','', '/');
}
}
/**
* ÆĶó¹ÌÅÍ °ªÀ» È®ÀÎ
*/
FirebaseChat.getParam = function (name){
var result = "";
var queryString = window.location.search;
var paramMap = {}
if (queryString == "") result = undefined;
if (typeof result != "undefined"){
var params = queryString.split("?")[1];
if (params == "") result = undefined;
if (typeof result != "undefined") {
var paramObj = params.split("&");
for (var i=0; i<paramObj.length; i++){
var datas = paramObj[i].split("=");
paramMap[datas[0]] = datas[1];
}
result = paramMap[name];
}
}
return result;
}
view rawindex.html hosted with ❤ by GitHub




getParam ¸Þ¼Òµå´Â URL¿¡ Æ÷ÇÔµÈ ÆĶó¹ÌÅÍ °ªÀ» È®ÀÎÇÏ´Â ¸Þ¼ÒµåÀÔ´Ï´Ù. roomId¸¦ È®ÀÎÇÏ´Â ¿ëµµÀÔ´Ï´Ù.äÆÃ¹æ ·Îµå°¡ ¿Ï·áµÈ ÈÄ URL¿¡¼­ roomId°ªÀ» È®ÀÎÇÏ°í äÆùæ¸ñ·Ï¿¡¼­ roomId °ªÀ» °¡Áø äÆùæÀ» Ŭ¸¯Çϸ鼭 äÆùæÀ» ¶ç¿ì°í, history.replaceState ¸Þ¼Òµå·Î È­¸é°»½Å¾øÀÌ URLÀ» ÃʱâÈ­ ÇØÁÝ´Ï´Ù.

½ÇÁ¦ Ǫ½Ã ¸Þ¼¼Áö º¸³»°í ¹Þ´Â °ÍÀ» Çغ¸±â À§Çؼ­´Â ¼­¹ö·Î ¹èÆ÷°¡ ÇÊ¿äÇÕ´Ï´Ù. Functions Äڵ尡 ¼­¹ö¿¡¼­ ±¸µ¿µÇ¾îÁ®¾ßÇϱ⠶§¹®ÀÔ´Ï´Ù. ·ÎÄÿ¡¼­ È£½ºÆÃÀ» ½ÇÇàÇÏ´Â firebase serve ¸í·É¾îÀÇ ¿É¼ÇÀ¸·Î FunctionsÄڵ嵵 °°ÀÌ ±¸µ¿ÇÒ ¼ö ÀÖÀ¸³ª ÀÌ´Â FunctionsÁß¿¡¼­µµ Hosting Æ®¸®°ÅÀÎ onRequest¸¸ °¡´ÉÇÕ´Ï´Ù. ±×·¯¹Ç·Î Firebase deploy¸í·É¾î·Î ÇÑ ¹ø ¹èÆ÷ÇÑ µÚ ½ÇÇàÇغ¸¼¼¿ä.




éÅÍ ¿Ï¼º ¼Ò½º  :




  1. ¿¹Á¦ ¼Ò°³
  2. Firebase ¼³Á¤Çϱâ
  3. HostingÀ» È°¿ëÇÑ ÇÁ·ÎÁ§Æ® Áغñ ÀÛ¾÷
  4. AuthenticationÀ» ÀÌ¿ëÇÑ À¯Àú °¡ÀÔ ¹× ·Î±×ÀÎ ±¸ÇöÇϱâ
  5. Realtime Database¸¦ ÀÌ¿ëÇÑ Ã¤Æñâ´É ±¸Çö - Reatime Database Ư¡ ¹× µ¥ÀÌÅÍ ±¸Á¶
  6. Realtime Database¸¦ ÀÌ¿ëÇÑ Ã¤Æñâ´É ±¸Çö - À¯Àúµ¥ÀÌÅÍ ÀúÀåÇϱâ
  7. Realtime Database¸¦ ÀÌ¿ëÇÑ Ã¤Æñâ´É ±¸Çö - À¯Àú¸®½ºÆà ȭ¸é
  8. Realtime Database¸¦ ÀÌ¿ëÇÑ Ã¤Æñâ´É ±¸Çö - äÆÃÈ­¸é ¹× äÆø޼¼Áö ¸®½ºÆÃ
  9. Realtime Database¸¦ ÀÌ¿ëÇÑ Ã¤Æñâ´É ±¸Çö - äÆø޼¼Áö Àü¼Û±â´É
  10. Realtime Database¸¦ ÀÌ¿ëÇÑ Ã¤Æñâ´É ±¸Çö - äÆÃ¹æ ¸®½ºÆÃÈ­¸é
  11. Realtime Database¸¦ ÀÌ¿ëÇÑ Ã¤Æñâ´É ±¸Çö - äÆùæ ÃÊ´ë ±â´É
  12. Realtime Database¸¦ ÀÌ¿ëÇÑ Ã¤Æñâ´É ±¸Çö - Á¢¼Ó ÁßÀÎ À¯Àú Ç¥½ÃÇϱâ
  13. Storage¸¦ ÀÌ¿ëÇÑ ÆÄÀÏ Àü¼Û±â´É
  14. Cloud Messaging°ú FunctionsÀ» ÀÌ¿ëÇÑ Çª½Ã¸Þ¼¼Áö ±â´É - FCM Token Á¤º¸ ÀúÀå
  15. Cloud Messaging°ú FunctionsÀ» ÀÌ¿ëÇÑ Çª½Ã¸Þ¼¼Áö ±â´É - Functions¸¦ ÅëÇÑ FCM ¹ß¼Û
  16. Cloud Messaging°ú FunctionsÀ» ÀÌ¿ëÇÑ Çª½Ã¸Þ¼¼Áö ±â´É - Service worker¸¦ ÀÌ¿ëÇÑ FCM¼ö½Å
  17. Realtime Database ±ÇÇÑ ¼³Á¤



Ãâó: http://cionman.tistory.com/66 [Suwoni-Codelab]