±âŸ(framework)
2018.03.21 / 01:53

Firebase Web äÆÃ¾Û ¸¸µé±â - Realtime Database¸¦ ÀÌ¿ëÇÑ Ã¤Æñâ´É ±¸Çö

ÈÞ°í
Ãßõ ¼ö 201


äÆÃ¹æ ¸®½ºÆà ȭ¸éÀÔ´Ï´Ù. ¾Æ·¡¿Í °°ÀÌ µÎ¹ø°ÅÇ¿¡ ÀÚ½ÅÀÌ ¼ÓÇØÀִ äÆÃ¹æ ¸ñ·ÏÀÌ ³ª¿À´Â È­¸é ÀÔ´Ï´Ù.


¸Þ¼¼Áö¸¦ ÀúÀåÇÒ ¶§ UserRoomsÀ§Ä¡¿¡µµ µ¥ÀÌÅ͸¦ ÀúÀåÇߴµ¥ ÀÌ À§Ä¡¿¡ ÀúÀåµÈ µ¥ÀÌÅ͸¦ äÆÃ¹æ ¸®½ºÆà ȭ¸é¿¡ È°¿ëÇÏ°Ô µË´Ï´Ù.

äÆÃ¹æ ¸®½ºÆ® È­¸éÀ» ¸¸µé±â À§ÇØ ´ÙÀ½ Äڵ带 Ãß°¡ÇØÁֽʽÿÀ.


<script>
/**
* Ãʱâ ÇÊµå º¯¼ö ÇÒ´ç
*/
FirebaseChat.prototype.init = function(){
//...»ý·«
this.dvInputChat = document.getElementById('dvInputChat');
this.ulRoomList = document.getElementById('ulRoomList');
}
/**
* ·Î±×ÀÎ ÈÄ ¼¼ÆÃ
*/
FirebaseChat.prototype.setLogin = function(user){ //user ÆĶó¹ÌÅÍ Ãß
//...»ý·«
this.loadRoomList(); //äÆÃ¹æ ¸ñ·ÏºÒ·¯¿À±â
}
/**
* µÎ¹ø° ÅÇ Ã¤ÆÃ¹æ ¸ñ·Ï¸®½ºÆ® È£Ãâ
*/
FirebaseChat.prototype.loadRoomList = function(){
this.roomTemplate = document.getElementById('templateRoomList').innerHTML;
var roomRef = this.database.ref('UserRooms/'+this.auth.currentUser.uid);
roomRef.off();
roomRef.orderByChild('timestamp').on('value', this.getRoomList.bind(this))
}
/**
* loadRoomList ¿¡¼­ µ¥ÀÌÅ͸¦ ¹Þ¾Æ¿ÔÀ» ¶§
*/
FirebaseChat.prototype.getRoomList = function(snapshot){
var arrRoomListHtml = [];
var cbDisplayRoomList = function(data){
var val = data.val();
var arrRoomUserName = val.roomUserName.split(this.SPLIT_CHAR);
arrRoomUserName.splice(arrRoomUserName.indexOf(this.auth.currentUser.displayName), 1); // ¹æ Á¦¸ñ ŸÀÌƲ¿¡¼­´Â ÀÚ½ÅÀÇ À̸§À» Á¦¿ÜÇÕ´Ï´Ù.
var eachRoomTitle = arrRoomUserName.length > 1 ?
arrRoomUserName[0] + " ¿Ü " + (arrRoomUserName.length - 1) + "¸í" : arrRoomUserName[0] +'´Ô';
if(data.key === this.roomId && this.isOpenRoom){ //µ¥ÀÌÅÍ Å°°¡ ÇöÀç ¹æID¿Í °°°í äÆùæÀÌ ¿­·ÁÀÖ´Â °æ¿ì¿¡ ÇöÀç ¸Þ¼¼Áö »ó´Ü Á¦¸ñÀ» °»½ÅÇØÁÝ´Ï´Ù.
this.spTitle.innerHTML = eachRoomTitle;
}
arrRoomListHtml.push( _.template(this.roomTemplate)({roomId : data.key, lastMessage:val.lastMessage,
profileImg : val.profileImg, roomTitle : eachRoomTitle, roomUserName:val.roomUserName,
roomUserlist: val.roomUserlist,
roomType : val.roomType, roomOneVSOneTarget : val.roomOneVSOneTarget,
datetime :FirebaseChat.timestampToTimeForRoomList(val.timestamp)}));
}
snapshot.forEach(cbDisplayRoomList.bind(this));
this.ulRoomList.innerHTML = arrRoomListHtml.reverse().join(''); // ¿ª¼ø Á¤·Ä
/**
* roomList Ŭ¸¯ À̺¥Æ® Àû¿ë
*/
var arrLiList = this.ulRoomList.getElementsByTagName('li')
var arrLiListLength = arrLiList.length;
for(var i=0; i < arrLiListLength; i++){
arrLiList[i].addEventListener('click', this.onRoomListClick.bind(this));
}
}
/**
* ·ë¸®½ºÆ® Ŭ¸¯
*/
FirebaseChat.prototype.onRoomListClick = function(event){
this.aBackBtn.classList.remove('hiddendiv');
this.aInvite.classList.remove('hiddendiv');
// ¸Þ¼¼Áö ·Îµå
this.roomId = event.currentTarget.getAttribute('data-roomId');
this.roomTitle = event.currentTarget.getAttribute('data-roomTitle');
this.roomUserlist = event.currentTarget.getAttribute('data-roomUserlist').split(this.SPLIT_CHAR); // ê¹æ À¯Àú¸®½ºÆ®
this.roomUserName = event.currentTarget.getAttribute('data-roomUserName').split(this.SPLIT_CHAR); // ê¹æ À¯Àú À̸§
this.openChatRoom(this.roomId, this.roomTitle);
// ¸Þ¼¼Áö È­¸é À̵¿
this.tabMessageList.click();
}
/**
* RoomList È­¸é ½Ã°£º¯È¯
*/
FirebaseChat.timestampToTimeForRoomList=function(timestamp){
var date = new Date(timestamp),
year = date.getFullYear(),
month = date.getMonth()+1,
day = date.getDate(),
hour = date.getHours(),
minute = date.getMinutes();
var nowDate = new Date(),
nowYear = nowDate.getFullYear(),
nowMonth = nowDate.getMonth()+1,
nowDay = nowDate.getDate(),
nowHour = nowDate.getHours(),
nowMinute = nowDate.getMinutes();
var result;
if(year === nowYear && month === nowMonth && day === nowDay){
result = FirebaseChat.pad(hour) +":" + FirebaseChat.pad(minute);
}else{
result = FirebaseChat.pad(year) +"-" + FirebaseChat.pad(month) + "-" + FirebaseChat.pad(day);
}
return result;
}
view rawindex.html hosted with ❤ by GitHub



äÆÃ¹æ ¸ñ·ÏÀ» ºÒ·¯¿À´Â ÄÚµåÀÔ´Ï´Ù. ·Î±×ÀÎ ÀÎÁõÀÌ ¿Ï·áµÈ ÈÄ ¼öÇàµÇ´Â setLogin ¸Þ¼Òµå ¾È¿¡¼­ loadRoomList¸Þ¼Òµå¸¦ È£ÃâÇÕ´Ï´Ù. 

loadRoomList¸Þ¼Òµå¸¦ È®ÀÎÀ» Çغ¸¸é À¯Àú¸®½ºÆ®¿Í ´Â ´Ù¸£°Ô ¸Þ¼¼Áö¸¦ ¹ÞÀ» ¶§¸¶´Ù ¸ñ·ÏÀ» °»½Å½ÃÄÑ ÁÖ±âÀ§ÇØ once¸Þ¼Òµå°¡ ¾Æ´Ñ on¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿´½À´Ï´Ù.  

getRoomList¸Þ¼Òµå´Â loadRoomList¿¡¼­ äÆÃ¹æ ¸ñ·ÏÀ» µ¥ÀÌÅ͸¦ ¹ÞÀ» ¶§¸¶´Ù È­¸éÀ» ¸¸µå´Â ¸Þ¼Òµå ÀÔ´Ï´Ù. underscore¶óÀ̺귯¸®ÀÇ template ¸Þ¼Òµå·Î È­¸éÀ» ±×¸³´Ï´Ù.

äÆÃ¹æ ¸ñ·ÏÀÇ µ¥ÀÌÅʹ äÆÃ¹æ »ó´Ü ŸÀÌƲÀ» °»½ÅÇϱâ À§ÇÑ ¿ëµµ·Îµµ »ç¿ëÀ̵˴ϴÙ. 

var arrRoomUserName val.roomUserName.split(this.SPLIT_CHAR);
arrRoomUserName.splice(arrRoomUserName.indexOf(this.auth.currentUser.displayName), 1); 
var eachRoomTitle arrRoomUserName.length ?

                                  arrRoomUserName[0] + " ¿Ü " + (arrRoomUserName.length 1) + "¸í" arrRoomUserName[0] +'´Ô';

if(data.key === this.roomId && this.isOpenRoom){ //ÇöÀç ¸Þ¼¼Áö »ó´Ü Á¦¸ñÀ» °»½ÅÇØÁØ´Ù.
       this.spTitle.innerHTML  eachRoomTitle;
} 

¹æ¸ñ·ÏÀ» Ŭ¸¯À» Çϸé äÆùæÀ» ¿ÀÇÂÇؾßÇϴµ¥ äÆùæÀ» ¿ÀÇÂÇϱâ À§Çؼ­ ÇÊ¿äÇÑ Á¤º¸¸¦ ¹Ì¸® °¢°¢ÀÇ Ã¤ÆùæÀ» °¨½Î´Â liű×ÀÇ data ¼Ó¼ºÀ¸·Î °ªÀ» ÀúÀåÇÕ´Ï´Ù. 

<!-- template äÆù渮½ºÆ® ¿µ¿ª -->
<script type="text/template" id="templateRoomList">
<li id="liRoom<%=roomId %>" data-roomId="<%=roomId %>" data-roomTitle='<%=roomTitle%>' data-roomUserName="<%=roomUserName%>"
data-roomType="<%=roomType%>" data-roomOneVSOneTarget="<%=roomOneVSOneTarget%>" data-roomUserlist="<%=roomUserlist %>" class="collection-item avatar" >
<img src="<%=profileImg ? profileImg : 'img/noprofile.png' %>" alt="" class="circle">
<span class="title"><%=roomTitle%></span>
<p><%=lastMessage %></p>
<a href="#!" class="secondary-content"> <%=datetime %></a>
</li>
</script>
view rawindex.html hosted with ❤ by GitHub




±×¸®°í äÆùæÀ» ¿ÀÇÂÇϴµ¥ Á¤º¸·Î »ç¿ëÇÒ µ¥ÀÌÅÍ ÀÌ¿Ü¿¡ roomTypeÀ̶ó´Â µ¥ÀÌÅÍ°¡ ÀÖ½À´Ï´Ù. roomTypeÀº 'ONE_VS_ONE' ¶Ç´Â 'MULTI' °ªÀÔ´Ï´Ù. 1´ë1 äÆùæÀÎÁö ¾Æ´Ï¸é 3¸íÀÌ»óÀÌ »ç¿ëÇϴ äÆùæÀÎÁö ±¸ºÐÇÏ´Â ±¸ºÐ°ªÀÔ´Ï´Ù. À¯Àú¸®½ºÆ®¿¡¼­ À¯Àú¸¦ Ŭ¸¯ÇÒ ½Ã¿¡ »õ·Î¿î äÆùæÀ» ¸¸µéÁö ¾Ê°í äÆÃ¹æ ¸®½ºÆ® È­¸éÀ» È®ÀÎÇؼ­ äÆùæÀ» ¿ÀÇÂÇϱâ À§ÇÑ ¿ëµµÀÔ´Ï´Ù. 

Realtime Database¿¡¼­´Â ¾Æ½±°Ôµµ ³»¸²Â÷¼øÀÇ Á¤·ÄÀÌ ¾ø½À´Ï´Ù. º¸Åë ³»¸² Â÷¼øÀ» À§ÇÑ µ¥ÀÌÅ͸¦ ÀúÀåÀ» ÇÏ´Â ¹æ¹ýÀ» ¾²°Å³ª ¾Æ·¡¿Í °°ÀÌ µ¥ÀÌÅ͸¦ ¹Þ¾Æ¼­ ¿ª¼øÀ¸·Î Á¤·ÄÇÕ´Ï´Ù. ÃÖ½ÅÀÇ ¸Þ¼¼Áö¸¦ ¹ÞÀº äÆùæÀ» °¡Àå »óÀ§¿¡ ¿Ã¸®±â À§Çؼ­ ¾Æ·¡¿Í °°ÀÌ ¹è¿­ °ªÀ» ¹Ý´ë·Î ¹Ù²Ù¾ú½À´Ï´Ù.
this.ulRoomList.innerHTML = arrRoomListHtml.reverse().join(''); // ¿ª¼ø Á¤·Ä
getRoomList ¸Þ¼Òµå ÇÏ´Ü¿¡´Â äÆùæÀ» Ŭ¸¯ÇÒ ½Ã ¹æÀ» ¿ÀÇÂÇÏ´Â µ¿ÀÛÀ» ÇÏ´Â onRoomListClick ¸Þ¼Òµå°¡ ¹ÙÀεù µÇ¾î ÀÖ½À´Ï´Ù.
var arrLiList this.ulRoomList.getElementsByTagName('li')
    var arrLiListLength arrLiList.length;
    for(var i=0arrLiListLengthi++){
        arrLiList[i].addEventListener('click'this.onRoomListClick.bind(this));
    }

onRoomListClick ¸Þ¼Òµå´Â äÆÃ¹æ ¸ñ·Ï È­¸é¿¡ ÀúÀåÇصРdata ¼Ó¼ºµéÀ» °¡Áö°í¿Í äÆùæÀ» ¿ÀÇÂÇϴµ¥ ÇÊ¿äÇÑ º¯¼ö¸¦ ¼³Á¤ÇÏ°í äÆùæÀ» ¿­¾î ÁÝ´Ï´Ù.

À¯Àú¸®½ºÆ® È­¸é Ŭ¸¯½Ã äÆÃ¹æ ¸ñ·ÏÀ» °Ë»ö ÈÄ ¿ÀÇÂÇÏ´Â ±â´ÉÀ» Ãß°¡ÇÏ°Ú½À´Ï´Ù. onUserListClick ¸Þ¼Òµå¸¦ ¾Æ·¡¿Í °°ÀÌ ¼öÁ¤ÇØÁÖ¼¼¿ä.

<script>
/**
* À¯Àú¸®½ºÆ® Ŭ¸¯
*/
FirebaseChat.prototype.onUserListClick = function(event){
this.aBackBtn.classList.remove('hiddendiv'); // ¹é¹öÆ° ³ëÃâ
this.aInvite.classList.remove('hiddendiv'); // ÃÊ´ë ¹öÆ° ³ëÅø
var targetUserUid = event.currentTarget.getAttribute('data-targetUserUid');
var targetUserName = event.currentTarget.getAttribute('data-username');
var roomListTarget = document.querySelectorAll('[data-roomType="'+ this.ONE_VS_ONE+'"][data-roomOneVSOneTarget="'+ targetUserUid +'"]')[0];
if(roomListTarget){ // null ÀÌ ¾Æ´Ï¸é
roomListTarget.click();
}else{
// ¸Þ¼¼Áö ·Îµå
this.roomTitle = targetUserName+'´Ô';
this.roomUserlist = [targetUserUid, this.auth.currentUser.uid]; // ê¹æ À¯Àú¸®½ºÆ®
this.roomUserName = [targetUserName, this.auth.currentUser.displayName] // ê¹æ À¯Àú À̸§
this.roomId = this.MAKEID_CHAR + this.auth.currentUser.uid + this.DATETIME_CHAR + FirebaseChat.yyyyMMddHHmmsss();
this.openChatRoom(this.roomId, this.roomTitle);
}
}
view rawindex.html hosted with ❤ by GitHub




¾Æ·¡ ÄÚµå ±¸¹®ÀÌ Ã¤ÆÃ¹æ ¸ñ·Ï¿¡¼­ 1´ë1 ŸÀÔÀÇ Ã¤Æùæ Áß¿¡ Ŭ¸¯ÇÑ À¯ÀúÀÇ uid ¸¦ ã´Â ÄÚµå ÀÔ´Ï´Ù.
var roomListTarget document.querySelectorAll('[data-roomType="'this.ONE_VS_ONE+'"][data-roomOneVSOneTarget="'targetUserUid +'"]')[0];

ÇØ´ç Ÿ°ÙÀÌ ÀÖ´Ù¸é äÆÃ¹æ ¸ñ·Ï¿¡¼­ ÇØ´çÇ׸ñÀ» Ŭ¸¯ÇϰԵǰí, ¾Æ´Ñ°æ¿ì´Â »õ·Î¿î äÆùæÀ» ¿ÀÇÂÇÏ°Ô µË´Ï´Ù.

À¯Àú¸®½ºÆ®¿¡¼­ äÆùæÀ» ¿ÀÇÂÇÏ´Â °Í°ú äÆù渮½ºÆ®¿¡¼­ äÆùæÀ» ¿ÀÇÂÇÏ´Â °ÍÀÌ ¿Ï¼ºµÇ¾ú½À´Ï´Ù. ÀÌÁ¦ äÆùæ È­¸é¿¡¼­ µÚ·Î °¡±â ¹öÆ°À» ´­·¶À» ½Ã¿¡ µ¿ÀÛÀ» ±¸ÇöÇÏ°Ú½À´Ï´Ù.

À¯Àú¸®½ºÆ®¿¡¼­ äÆùæÀ» ¿ÀÇÂÇÏ¿´´ÂÁö ¾Æ´Ï¸é äÆÃ¹æ ¸®½ºÆ®¿¡¼­ äÆùæÀ» ¿ÀÇÂÇÏ¿´´ÂÁö ±¸ºÐ °ªÀÌ ÇÊ¿äÇÕ´Ï´Ù. onUserListClick ¸Þ¼Òµå¿Í onRoomListClick ¸Þ¼Òµå¿¡ Äڵ带 Ãß°¡ÇØÁֽʽÿÀ.

<script>
/**
* À¯Àú¸®½ºÆ® Ŭ¸¯
*/
FirebaseChat.prototype.onUserListClick = function(event){
this.roomFlag ='tabUserList';
//...»ý·«
}
/**
* ·ë¸®½ºÆ® Ŭ¸¯
*/
FirebaseChat.prototype.onRoomListClick = function(event){
this.roomFlag ='tabRoomList';
//...»ý·«
}
view rawindex.html hosted with ❤ by GitHub




±×¸®°í äÆùæ È­¸éÀÇ ÁÂÃø »ó´Ü ¹é¹öÆ°¿¡ À̺¥Æ®¸¦ ¹ÙÀεùÇÏ°í ¸Þ¼Òµå¸¦ ¿¬°áÇÏ°Ú½À´Ï´Ù.

<script>
/**
* Ãʱâ ÇÊµå º¯¼ö ÇÒ´ç
*/
FirebaseChat.prototype.init = function(){
//...»ý·«
this.ORIGIN_TITLE = "Firebase-Tutorial";
}
/**
* Ãʱâ À̺¥Æ® ¹ÙÀεù
*/
FirebaseChat.prototype.initEvent = function(){
//...»ý·«
this.aBackBtn.addEventListener('click', this.onBackBtnClick.bind(this));
}
/**
* ¹é¹öÆ° Ŭ¸¯
*/
FirebaseChat.prototype.onBackBtnClick = function(){
this.isOpenRoom = false;
this.aBackBtn.classList.add('hiddendiv');
this.aInvite.classList.add('hiddendiv');
document.getElementById(this.roomFlag).click();
this.spTitle.innerText = this.ORIGIN_TITLE;
this.ulMessageList.innerHTML='';
}
view rawindex.html hosted with ❤ by GitHub




¹é¹öÆ°¿¡ onBackBtnClick ¸Þ¼Òµå¸¦ ¿¬°áÇÏ¿´½À´Ï´Ù. onBackBtnClick¸Þ¼Òµå´Â ¹æ ¿ÀÇ ¿©ºÎ »óÅ°ªÀ» false·Î º¯°æÇÏ°í, ¹é¹öÆ°°ú ÃÊ´ë ¹öÆ°À» ¼û±â°í, äÆÃ¹æ ¿ÀÇ Àü ÅÇÀ¸·Î µÇµ¹¾Æ°¡¸ç, »ó´ÜŸÀÌƲÀ» º¹¿øÇÏ´Â Äڵ尡 µé¾î°¡ ÀÖ½À´Ï´Ù.

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

 8.Realtime Database를 이용한 채팅기능 구현 - 채팅방 리스





  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/60 [Suwoni-Codelab]