ALL. TRIPMATE - jmini1234/tripmate GitHub Wiki

0. tripmate๋ž€?

ํŠธ๋ฆฝ๋ฉ”์ดํŠธ ์ฑ„ํŒ… ์›น https://triptmate.firebaseapp.com

1. Tripmate์˜ ๋ชฉ์ 

์ฃผ์š” ๋„์‹œ๋ฅผ ์—ฌํ–‰ํ•˜๋Š” ์—ฌํ–‰๊ฐ๋“ค๊ณผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ •๋ณด๋ฅผ ๊ณต์œ ํ•˜๋Š” ์ฑ„ํŒ… ์•ฑ

'๊ณ„ํš' ์œ„์ฃผ์˜ ์—ฌํ–‰ ์–ดํ”Œ์„ ํƒ€ํŒŒํ•˜๋‹ค!

๊ฐ™์€ ์ง€์—ญ, ๋™์‹œ๊ฐ„๋Œ€๋ฅผ ํ•จ๊ป˜ ์—ฌํ–‰ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค๊ณผ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…์„ ํ•จ์œผ๋กœ์จ, ํœด์—…ํ•˜๋Š” ๊ฐ€๊ฒŒ, ์„ธ์ผ์ •๋ณด, ๋„๋กœ ์ •๋ณด ๋“ฑ๋“ฑ ๋‚ ๋งˆ๋‹ค ๋ฐ”๋€Œ๋Š” ์ •๋ณด๋ฅผ ์–ป์–ด ์„œ๋กœ์˜ ์—ฌํ–‰์„ ์พŒ์ ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ์„œ๋น„์Šค!

1. ๊ฐ™์€ ์ง€์—ญ์„ ์—ฌํ–‰ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค๊ฐ„ ์‹ค์‹œ๊ฐ„ ์ •๋ณด ๊ณต์œ 

๊ฐ™์€ ์ง€์—ญ, ๋™์‹œ๊ฐ„๋Œ€๋ฅผ ํ•จ๊ป˜ ์—ฌํ–‰ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค๊ณผ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…์„ ํ•จ์œผ๋กœ์จ ๊ถ๊ธˆํ•œ ์ ์„ ๋ฐ”๋กœ๋ฐ”๋กœ ๋ฌป๊ณ  ๋‹ตํ•˜๋ฉฐ ํ˜„์žฌ ์ƒํ™ฉ์— ๋งž๋Š” ์ •๋ณด๋ฅผ ์ฆ‰๊ฐ ์•Œ ์ˆ˜ ์žˆ๊ณ , ๊ณ„ํšํ•œ ์—ฌํ–‰์˜ ๋ณ€์ˆ˜๋ฅผ ์ตœ๋Œ€ํ•œ ์ค„์ด๋„๋ก ๋„์™€๋“œ๋ฆฝ๋‹ˆ๋‹ค.

2. ๊ทธ ์ง€์—ญ์„ ์—ฌํ–‰๊ฐˆ ์‚ฌ๋žŒ๋“ค์˜ ์ •๋ณด ์ˆ˜์ง‘

๋˜ํ•œ ์—ฌํ–‰์ง€์— ์—†๋Š” ์‚ฌ๋žŒ ๊ฐ™์€ ๊ฒฝ์šฐ, ํ˜„์žฌ ์—ฌํ–‰ํ•˜๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์˜ ์‹ค์‹œ๊ฐ„ ์ •๋ณด๋ฅผ ๋ด„์œผ๋กœ์จ ์ž์‹ ์˜ ์—ฌํ–‰์„ ๊ณ„ํšํ•˜๋Š”๋ฐ ์ฐธ๊ณ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ์œ ์šฉํ•œ ์ •๋ณด๋Š” ๋งˆ์ดํŽ˜์ด์ง€์— ์ €์žฅ

๋‹น์žฅ ๋‚ด์ผ, ํ•œ๋‹ฌ ํ›„์˜ ์—ฌํ–‰ ๊ณ„ํš์— ์œ ์šฉํ•œ ์š”์†Œ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ถ๋งˆํฌ๋ฅผ ํ†ตํ•ด ๋งˆ์ดํŽ˜์ด์ง€์— ์ €์žฅํ•˜์—ฌ, ๋‚ด ๊ณ„ํš์— ์ฐธ๊ณ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4. ์œ„์น˜๋ฅผ ํ†ตํ•œ ๋ฉ”์„ธ์ง€ ์‹ ๋ขฐ์„ฑ ๋ณด์žฅ

์ฑ„ํŒ…์„ ์ด์šฉํ•œ ์—ฌํ–‰์ง€ ์ •๋ณด ๊ฐ™์€ ๊ฒฝ์šฐ ๋ฐœ์‹ ์ž์˜ ์œ„์น˜์ •๋ณด๋ฅผ ํ™•์ธํ•˜์—ฌ ๋ฉ”์„ธ์ง€์˜ ์‹ ๋ขฐ์„ฑ์„ ์ˆ˜์‹ ์ž๊ฐ€ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


2. tripmate ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

ํŠธ๋ฆฝ๋ฉ”์ดํŠธ ์ฑ„ํŒ… ์›น https://triptmate.firebaseapp.com

2-1. ์›น ๋ฒ„์ „

ใ„ฑ. ๋กœ๊ทธ์ธ

images

๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๊ตฌ๊ธ€๊ณผ ์—ฐ๋™ํ•ด์„œ ๋กœ๊ทธ์ธ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ใ„ด.์ฑ„ํŒ…๋ฐฉ ์ž…์žฅ

images

GO CHAT ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ฑ„ํŒ…๋ฐฉ์— ์ž…์žฅ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ใ„ท. ์›ํ•˜๋Š” ๋„์‹œ์˜ ์ฑ„ํŒ…๋ฐฉ ์„ ํƒ

images

์ •๋ณด๋ฅผ ์–ป๊ณ ์žํ•˜๋Š” ์ฑ„ํŒ…๋ฐฉ์„ ์„ ํƒํ•œ๋‹ค.

ใ„น. ์ฑ„ํŒ…๋ฐฉ ์ž…์žฅ

images

๊ฐ ์ฑ„ํŒ…๋ฐฉ๋งˆ๋‹ค ๊ทธ ๋‚˜๋ผ์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ง„ ์ฑ„ํŒ…๋“ค์ด ๋“ค์–ด์žˆ๋‹ค.

ใ„น-1. ์ฑ„ํŒ…ํ•œ ์œ„์น˜ ๋ฐ˜ํ™˜

์ •๋ณด์˜ ์‹ ๋ขฐ์„ฑ์„ ์œ„ํ•ด ์ฑ„ํŒ…์„ ์“ด ์‚ฌ๋žŒ์˜ ์œ„์น˜์™€ ๋‚ ์งœ๊ฐ€ ์˜ค๋ฅธ์ชฝ ํ•˜๋‹จ์— ์ถœ๋ ฅ๋œ๋‹ค.

ใ„น-2. ๋ถ๋งˆํฌ

ํ˜„์žฌ ์œ„์น˜์™€ ๊ฐ™์ด ๋†“์—ฌ์žˆ๋Š” ๋ฒ„ํŠผ์€ ๋ถ๋งˆํฌ , ์ €์žฅ ๊ธฐ๋Šฅ์ด๋‹ค. ๋ถ๋งˆํฌ๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋งˆ์ดํŽ˜์ด์ง€์— ํ•ด๋‹น ์ฑ„ํŒ… ์ •๋ณด๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ๋‹ค.

image

ใ…. ๋งˆ์ดํŽ˜์ด์ง€

์ƒ๋‹จ ์˜ค๋ฅธ์ชฝ์˜ ๊ณ„์ •์ •๋ณด๊ฐ€ ์žˆ๋Š” ๊ณณ์„ ๋ˆ„๋ฅด๋ฉด ๋งˆ์ดํŽ˜์ด์ง€๋กœ ์ด๋™ํ•œ๋‹ค.

image

์ „๋ฐ˜์ ์ธ ๋งˆ์ดํŽ˜์ด์ง€ ํ™”๋ฉด์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

image

ใ…-1. ํ˜„์žฌ ์œ„์น˜ ๋ฐ˜ํ™˜

์‚ฌ์šฉ์ž๊ฐ€ ์žˆ๋Š” ๊ณณ์—๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ตฌ๊ธ€ Map์„ ํ†ตํ•ด ์•Œ๋ ค์ค€๋‹ค.

image

ใ…-2. ๋ถ๋งˆํฌ ์ •๋ณด ๋ฐ˜ํ™˜

๋ถ๋งˆํฌ ์„ธ์…˜์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ถ๋งˆํฌ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €๋˜ ์ฑ„ํŒ…์˜ ๋‚ด์šฉ๊ณผ ๊ทธ ์ฑ„ํŒ…๋ฐฉ์˜ ์ •๋ณด๊ฐ€ ์“ฐ์—ฌ์žˆ๋‹ค.

image

2-2. ์›น์•ฑ ๋ฒ„์ „


I. DB ์„ค๊ณ„ ๋ฐ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

1. DB ์„ค๊ณ„

Firebase Realtime Database

์ผ๋ฐ˜์ ์ธ HTTP ์š”์ฒญ์ด ์•„๋‹Œ ๋™๊ธฐํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ๊ธฐ๊ธฐ๊ฐ€ ์ˆ˜ ๋ฐ€๋ฆฌ์ดˆ ๋‚ด์— ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜์‹ ํ•œ๋‹ค.

"fcmTokens":{
    "token-key":"token-value", 
    ...
}
"messages":{
    "BERLIN(GERMANY)":{
        "message_image_key":{
            "imageUrl":"profile URL",
            "location":"location info",
            "name": "current username",
            "storageUrl":"image file URL",
            "time":"sending time"
        }, 
        "message_text_key":{
            "imageUrl":"profile URL",
            "location":"location info",
            "name": "current username",
            "text":"input text",
            "time":"sending time"
        },
        ...
    }, 
    "DANANG(VIETNAM)": {...},
    ...
}
"status":{
    "username":{
        "bookmark":{
            "bookmarkkey":{
                "image":"bookmark image URL",
                "status": "room name",
                "time":"message time"
            },
            ...
        },
        "location":{
            "status":"current room name"
        }
    },
    ...
}

2. ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

project Structure

tripmate
โ”œโ”€ .firebase
โ”œโ”€ .git
โ”œโ”€ functions
โ”‚  โ”œโ”€ .eslintrc.json
โ”‚  โ”œโ”€ index.js
โ”‚  โ”œโ”€ package.json
โ”œโ”€ public
โ”‚  โ”œโ”€ images
โ”‚  โ”œโ”€ scripts
โ”‚  |  โ”œโ”€ list.js
โ”‚  |  โ”œโ”€ login.js
โ”‚  |  โ”œโ”€ main.js
โ”‚  |  โ”œโ”€ map.js
โ”‚  โ”œโ”€ styles
โ”‚  |  โ”œโ”€ index.css
โ”‚  |  โ”œโ”€ list.css
โ”‚  |  โ”œโ”€ main.css
โ”‚  |  โ”œโ”€ map.css
โ”‚  โ”œโ”€ favicon.ico
โ”‚  โ”œโ”€ firebase-messaging-sw.js
โ”‚  โ”œโ”€ index.html
โ”‚  โ”œโ”€ list.html
โ”‚  โ”œโ”€ main.html
โ”‚  โ”œโ”€ manifest.json
โ”‚  โ”œโ”€ test.html
โ”œโ”€ .firebaserc
โ”œโ”€ .gitignore
โ”œโ”€ database-rules.json
โ”œโ”€ firebase.json
โ”œโ”€ storage.rules
โ””โ”€ README.md

II. FrontEnd

1. JavaScript์™€ HTML ์—ฐ๋™

ใ„ฑ. ์ฑ„ํŒ…๋ฐฉ ๋ชฉ๋ก ๋งŒ๋“ค๊ธฐ

var List_TEMPLATE_BEFORE =
      "<li class='mdl-list__item'>" +
        "<span class='mdl-list__item-primary-content'>"+
          "<i class='material-icons mdl-list__item-icon'>chat</i>"+
          "<a class='name'  href='#'";
var List_TEMPLATE_AFTER =
      ">go</a>"+
        '</span>'+
      '</li>';

function displayList(roomlist) {
  var htmlelt = document.getElementById("lists");

  for(var room in roomlist){
    var divtag = document.createElement( 'div' );
    divtag.innerHTML = List_TEMPLATE_BEFORE + "id = "+roomlist[room]+List_TEMPLATE_AFTER;
    divtag.querySelector('.name').innerHTML = roomlist[room];
    htmlelt.appendChild(divtag);
  }
  listening(roomlist);
}

List_TEMPLATE๋ฅผ ๋งŒ๋“ค์–ด ๋ถˆ๋Ÿฌ์˜ฌ ์ฑ„ํŒ…๋ฐฉ ๋ชฉ๋ก์˜ ํ˜•์‹์„ ์ง€์ •ํ•˜์˜€๋‹ค. li ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฑ„ํŒ…๋ฐฉ ๋ชฉ๋ก์„ list.html ํŒŒ์ผ์— ๋ฆฌ์ŠคํŠธ ํ˜•์‹์œผ๋กœ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.

htmlelt ๋ณ€์ˆ˜๋Š” list.html ํŒŒ์ผ์—์„œ ID๊ฐ€ lists์ธ ํƒœ๊ทธ๋ฅผ ๊ฐ€์ ธ์™€ ์„ ์–ธํ•œ๋‹ค.

roomlist์— ์žˆ๋Š” ์ฑ„ํŒ…๋ฐฉ๋งˆ๋‹ค div ํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ณ , innerHTML์œผ๋กœ div ํƒœ๊ทธ ์•ˆ์˜ ๋‚ด์šฉ์„ List_TEMPLATE์˜ ํ˜•์‹์„ ์ด์šฉํ•˜์—ฌ ๋ณ€๊ฒฝํ•œ๋‹ค.

ใ„ด. ๋งˆ์ดํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

var List_TEMPLATE =
      "<li class='mdl-list__item'>" +
      '<div class="status"></div>'+
        '<div class="time"></div>'+
        '<div class="message"></div>'+
      '</li>';

function displayBook(datas){
  var messageListElement = document.getElementById('messages');
  var htmlelt = document.getElementById("lists");
  var divtag = document.createElement( 'div' );
  divtag.innerHTML = List_TEMPLATE;
  ...

๋งˆ์ดํŽ˜์ด์ง€์— ๋ถ๋งˆํฌํ•œ ๋‚ด์šฉ๋“ค์„ ๊ฐ€์ ธ์˜ฌ๋•Œ๋„ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•˜์˜€๋‹ค.

List_TEMPLATE์— ๋ถ๋งˆํฌ๋ฅผ ๊ฐ€์ ธ์˜ฌ ํ˜•์‹์„ ์œ„์น˜, ์‹œ๊ฐ„, ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ์„ ๋‚˜๋ˆ„์–ด ์ง€์ •ํ•˜์˜€๋‹ค.

  • getelementbyId() : ID๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•ด๋‹น HTML ์š”์†Œ(ํƒœ๊ทธ)๋ฅผ ๋ฐ›์•„์˜จ๋‹ค
  • innerHTML=' ' : ์„ ํƒํ•œ HTML ์š”์†Œ ์•ˆ์˜ ๋‚ด์šฉ์„ ' ' ์•ˆ์˜ ๋‚ด์šฉ์œผ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

2. Google Material Design Lite ์‚ฌ์šฉ

<header class="mdl-layout__header">
        <div class="mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-grid">
          <div class="mdl-layout__header-row mdl-cell mdl-cell--10-col mdl-cell--10-col-tablet mdl-cell--10-col-desktop">
            <img class="logo" src="images/logo_png_1.png" alt="Tripmate" height="30px">
            <img class="logo" src="images/logo_png_0.png" alt="Tripmate" height="30px">
          </div>
          <div id="user-container">
            <div hidden id="user-pic" onclick="location.href='./map.html'"></div>
            <div hidden id="user-name" onclick="location.href='./map.html'"></div>
          </div>
        </div>
      </header>

๊ณ ์ • ํ—ค๋”์™€ ๋ฐ”๋””์˜ ๊ธฐ๋ณธ์ ์ธ ๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ์— google material design lite๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋˜ํ•œ mdl์„ ์ด์šฉํ•˜์—ฌ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

ex)

  • mdl-grid : ํ•ด๋‹น container๋ฅผ MDL grid component๋กœ ์ •์˜ํ•œ๋‹ค.
  • mdl-cell : container๋ฅผ MDL cell๋กœ ์ •์˜ํ•œ๋‹ค.
  • mdl-cell--N-col : 1๋ถ€ํ„ฐ 12๊นŒ์ง€ column์˜ size๋ฅผ ์ง€์ •ํ•œ๋‹ค.

3. CSS ์ ์šฉ

.mdl-list__item .message {
  display:inline-block;
  float:left;
  font-size: 14px;
  box-sizing:border-box;
  padding:4px;
  margin-right:4px;
  text-align: left;
  width:100%;
}
@media screen and (max-width: 610px) {

  #user-container #user-pic {
    top: 2px;
    width: 33px;
    height: 33px;
    background-size: 33px;
  }
}

CSS ์„ ํƒ์ž๋ฅผ ์ด์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ์š”์†Œ๋“ค์— ์„ธ๋ถ€์ ์ธ ์œ„์น˜, ํฌ๊ธฐ, ์—ฌ๋ฐฑ ๋“ฑ์˜ ๋””์ž์ธ์„ ์ ์šฉํ•œ๋‹ค.

๋ฏธ๋””์–ด์ฟผ๋ฆฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ์„ ์ ์šฉํ•œ๋‹ค.

III. Google API

1. Google Map API

1.1 Google Map ์ถœ๋ ฅ

var map, infowindow, pos, geocoder;

function initMap() {

  map = new google.maps.Map(document.getElementById('map'), {

    center: {lat: -34.397, lng: 150.644},

    zoom: 6

  });

  infowindow = new google.maps.InfoWindow;

  geocoder = new google.maps.Geocoder;

map ๋ณ€์ˆ˜๋Š” html tag ์ค‘ id ๊ฐ’์ด map์ธ ํ™”๋ฉด์„ ๋ฐ›์•„์„œ ์„ ์–ธํ•œ๋‹ค.

google map api๋ฅผ ํ†ตํ•ด infowindow์™€ geocoder ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•œ๋‹ค.

  • infowindow : ํ˜„์žฌ ์ •๋ณด์™€ ๊ด€๋ จ๋œ window ํ™”๋ฉด์ด๋‹ค.
  • geocoder : ์œ„์น˜๋ฅผ ์œ„๋„์™€ ๊ฒฝ๋„๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค.

1.2 ํ˜„์žฌ ์œ„์น˜ ์ขŒํ‘œ ๋ฐ˜ํ™˜

  // Try HTML5 geolocation.

  if (navigator.geolocation) {

    navigator.geolocation.getCurrentPosition(function(position) {

      pos = {

        lat: position.coords.latitude,

        lng: position.coords.longitude

      };


      infowindow.setPosition(pos);

      infowindow.setContent('Location found.');

      infowindow.open(map);

      map.setCenter(pos);

      geocodeLatLng(geocoder, map, infowindow);

    }, function() {

      handleLocationError(true, infowindow, map.getCenter());

    });

  } else {

    // Browser doesn't support Geolocation

    handleLocationError(false, infowindow, map.getCenter());

  }

}

initMap() : ๋‚ด ์œ„์น˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” Map์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.

navigator.geolocation.getCurrentPosition ๋ฉ”์†Œ๋“œ๋กœ position ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด pos ์— ํ˜„์žฌ ์œ„๋„์™€ ๊ฒฝ๋„ ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค.

infowindow.setPosition(pos) ๋กœ ํ˜„์žฌ ์œ„์น˜์™€ ๊ด€๋ จ๋œ ์ง€๋„๋ฅผ ํ™”๋ฉด์— ๋ณด์—ฌ์ฃผ๊ณ  map์„ open ํ•ด์„œ ํ™”๋ฉด์— ๋„์šด๋‹ค.

์ด ๊ณณ์—์„œ geocodeLatLng(geocoder, map, infowindow) (1.3 ์ฐธ์กฐ) ํ•จ์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์™€์„œ ์‹ค์ œ ์ฃผ์†Œ ๊ฐ’๊นŒ์ง€ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

1.3 ์ขŒํ‘œ๋ฅผ ์ฃผ์†Œ๋กœ ๋ณ€๊ฒฝ (reverse Geocoding)

var address ;

function geocodeLatLng(geocoder, map, infowindow) {

        geocoder.geocode({'location': pos}, function(results, status) {

          if (status === 'OK') {

            if (results[0]) {

              map.setZoom(11);

              var marker = new google.maps.Marker({

                position: pos,

                map: map

              });

              infowindow.setContent(results[0].formatted_address);

              address=results[0].formatted_address;

              infowindow.open(map, marker);
			var lat = document.getElementById("location");
              lat.innerHTML = address;

            } else {

              window.alert('No results found');

            }

          } else {

            window.alert('Geocoder failed due to: ' + status);

          }

        });

      }

ํ˜„์žฌ ์œ„์น˜๋กœ ๋ฐ›์•„์˜จ ์œ„๋„ ๊ฒฝ๋„ ๊ฐ’์„ ์ฃผ์†Œ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” geocodeLatLng ํ•จ์ˆ˜

Map์„ pos(ํ˜„์žฌ ์œ„์น˜)๋กœ Zoom์„ํ•˜๊ณ  marker ํ‘œ์‹œํ•ด ๊ทธ ๊ณณ์— setContent๋กœ ์ฃผ์†Œ๋ฅผ ํ™”๋ฉด์— ์ถœ๋ ฅํ•œ๋‹ค.

pos์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” ์œ„๋„ ๊ฒฝ๋„ ๊ฐ’์„ result[0]์— ๋„ฃ๊ณ  formatted_address๋ฅผ ์‚ฌ์šฉํ•ด์„œ adress ๋ณ€์ˆ˜์— ์‹ค์ œ ์ฃผ์†Œ๋ฅผ ์ €์žฅํ•œ๋‹ค.

id๊ฐ€ location์ธ ํ™”๋ฉด์„ ์ฐพ์•„ lat์œผ๋กœ ์ •์˜ํ•œ ๋‹ค์Œ ๊ทธ ํ™”๋ฉด์— ํ˜„์žฌ ์ฃผ์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ์œ„ํ•ด innerHTML ์„ ์‚ฌ์šฉํ•ด์„œ address๋ฅผ ํ‘œ์‹œํ•œ๋‹ค.


2. Google Map - Firebase ์—ฐ๋™

2.1 firebase ์—ฐ๋™

  <script src="/__/firebase/5.5.8/firebase-app.js"></script>
    <script src="/__/firebase/5.5.8/firebase-auth.js"></script>
    <script src="/__/firebase/5.5.8/firebase-database.js"></script>
    <script src="/__/firebase/5.5.8/firebase-storage.js"></script>
    <script src="/__/firebase/5.5.8/firebase-messaging.js"></script>
    <script src="/__/firebase/init.js"></script>

    <script src="https://cdn.firebase.com/js/client/2.3.2/firebase.js"></script>

์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์˜ database๊ฐ€ ์ €์žฅ๋œ firebase ์„ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด firebase์˜ source๋ฅผ script๋ฅผ ํ†ตํ•ด์„œ ๋„ฃ์–ด์ค€๋‹ค.

2.2 Google Map ์—ฐ๋™

    <script src="scripts/map.js"></script>

    <script async defer

    src="https://maps.googleapis.com/maps/api/js?key=[Google_API_KEY]&callback=initMap">

    </script>

firebase-Google Map ์—ฐ๋™์„ ์œ„ํ•ด firebase.js๋ฅผ ์ฐธ์กฐํ•˜๋Š” script์™€ google api key๋ฅผ ๋„ฃ์€ script๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.


IV. Firebase Service ๊ด€๋ฆฌ

1. Service ํ™˜๊ฒฝ์„ค์ •๊ณผ ์‚ฌ์šฉ

์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•œ Firebase Service 4๊ฐ€์ง€Authentication, Database, Storage, Hosting๋Š” ๊ฐ๊ฐ์˜ ์„ค์ •์„ ๋ชจ๋‘ console์—์„œ ํ•œ ํ›„์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
๊ฐ develop ํ™˜๊ฒฝ์„ค์ •์‹œ ์ฃผ์˜์ ๊ณผ ๊ณตํ†ต์ ์ธ ์‚ฌ์šฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž.

1-1. Authentication

ํ™˜๊ฒฝ์„ค์ • : google ๋กœ๊ทธ์ธ ํ—ˆ์šฉ

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•: firebase.auth()

 var provider = new firebase.auth.GoogleAuthProvider();
 firebase.auth().signInWithPopup(provider).then(function(authData) {
    console.log(authData);
  }).catch(function(error) {
    console.log(error);
  });

google ๋กœ๊ทธ์ธ์„ ์‚ฌ์šฉํ• ๋•Œ๋Š” ๋ณ„๋„์˜ google login ๋ฉ”์†Œ๋“œ์ธ GoogleAuthProvider()๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ˜„์žฌ ์‚ฌ์šฉ์ž์˜ firebase.auth() ์ •๋ณด๋ฅผ initializeํ•œ๋‹ค.

์œ„ ์„ธํŒ… (sign in method) ์ดํ›„ firebase.auth() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ํ˜„์žฌ ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ์ •๋ณด์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด ๋“œ๋Ÿฌ๋‚˜๋ฉฐ, firebase.auth()๋ฅผ ์ด์šฉํ•ด์„œ ํ˜„์žฌ user์˜ id, profile, token ๋“ฑ์„ ์ž์‹ ์˜ ์„œ๋น„์Šค์— customizingํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

firebase.auth().signInWithPopup(provider);
firebase.auth().signOut();
firebase.auth().onAuthStateChanged(authStateObserver);
firebase.auth().currentUser.photoURL;
firebase.auth().currentUser.displayName;

1-2. Database

ํ™˜๊ฒฝ์„ค์ • : rule ์„ค์ •

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•: firebase.database()

Database๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ณด์•ˆ๊ทœ์น™(security rule)์„ ์„ค์ •ํ•ด์•ผํ•œ๋‹ค. ์ด๋•Œ ๊ทœ์น™์€ console์—์„œ ์„ค์ •ํ• ์ˆ˜ ์žˆ์œผ๋ฉฐ, rules๋ผ๋Š” key์˜ value ๊ฐ’์ด firebase database์˜ ๋ณด์•ˆ๊ทœ์น™์ด๋œ๋‹ค. value ๊ฐ’์— ๋“ค์–ด๊ฐ€๋Š” json data๋Š” .read, .write๋“ฑ ๋‹ค์–‘ํ•œ ์†์„ฑ์— ๋Œ€ํ•ด์„œ true, false๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

์œ„ ์„ธํŒ… (console setting) ์ดํ›„ firebase.database() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์˜ database๋ฅผ ์ ‘๊ทผํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. firebase.database()๋ฅผ ์ด์šฉํ•ด์„œ MySQL, MongoDB์˜ query๋ฌธ๊ณผ ๊ฐ™์€ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. database() ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ, DB ์ €์žฅ ๋ฐ ์—ฐ๊ฒฐ์„ ์œ„ํ•œ ๊ด€๋ฆฌ๋Š” ๋ณธ ์œ„ํ‚ค์˜ 3. Database ๋ฉ”์†Œ๋“œ ํ™œ์šฉ์ •๋ฆฌ(#3. Database ๋ฉ”์†Œ๋“œ ํ™œ์šฉ ์ •๋ฆฌ) ์—์„œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ํ™•์ธํ•˜์ž.

1-3. Storage

ํ™˜๊ฒฝ์„ค์ • : rule ์„ค์ •

**๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ• **: firebase.storage()

Database์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ storage๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋„ ๋ฒ„ํ‚ท๊ทœ์น™(bucket rule)์„ ์„ค์ •ํ•ด์•ผํ•œ๋‹ค. ์ด๋•Œ ๊ทœ์น™์€ console์—์„œ ์„ค์ •ํ• ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ์•ˆ์—๋Š” file์„ ์ €์žฅ(write)ํ• ๋•Œ์˜ ์ด๋ฆ„ ๊ทœ์น™ ๋ฐ, imagemaxsize์— ๊ด€ํ•œ ์„ค์ •์ด ์ด๋ฃจ์–ด์ ธ์ž‡๋‹ค.

// Returns true if the uploaded file is an image and its size is below the given number of MB.
function isImageBelowMaxSize(maxSizeMB) {
  return request.resource.size < maxSizeMB * 1024 * 1024
      && request.resource.contentType.matches('image/.*');
}

service firebase.storage {
  match /b/{bucket}/o {
    match /{userId}/{messageId}/{fileName} {
      allow write: if request.auth != null && request.auth.uid == userId && isImageBelowMaxSize(5);
      allow read;
    }
  }
}

์œ„ ์„ธํŒ… (console setting) ์ดํ›„ firebase.storage() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์˜ storage๋ฅผ ์ ‘๊ทผํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. database์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ref("๊ฒฝ๋กœ")๋ฅผ ์ด์šฉํ•ด์„œ ์ €์žฅ ํ˜น์€ ์ ‘๊ทผํ•  ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•˜๊ณ , .put() ๋“ฑ์„ ์ด์šฉํ•ด์„œ writeํ•œ๋‹ค.

firebase.storage().ref(filePath).put(file)

1-4. Hosting

ํ™˜๊ฒฝ์„ค์ • : ํ˜„์žฌ ๊ฐœ๋ฐœ์ค‘์ธ firebase ํ”„๋กœ์ ํŠธ์˜ deploy

firebase login
firebase use --add    #firebase ํ”„๋กœ์ ํŠธ ์„ ํƒ ํ›„ alias ๋ถ€์—ฌ

# firebase ํ”„๋กœ์ ํŠธ local ์„œ๋ฒ„๋กœ ํ™•์ธํ•˜๊ธฐ
firebase serve
firebase serve --only hosting

# firebase์—์„œ ์ œ๊ณตํ•˜๋Š” hosting์„ ์‚ฌ์šฉํ•˜์—ฌ deployํ•˜๊ธฐ
# ๋ณธ ํ”„๋กœ์ ํŠธ๋Š” firebase์—์„œ ์ œ๊ณตํ•˜๋Š” function์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— exception function์„ ์‚ฌ์šฉํ•ด์„œ deployํ•˜์˜€๋‹ค. 
firebase deploy
firebase deploy --except function

local hosting์„ ์ด์šฉํ•ด์„œ ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์˜ ์ง„ํ–‰์‚ฌํ•ญ์„ ์ฒดํฌํ•˜๊ณ ,

ํ”„๋กœ์ ํŠธ๊ฐ€ ๋งˆ๋ฌด๋ฆฌ ๋˜๋ฉด deploy๋ฅผ ํ•˜์—ฌ ํ”„๋กœ์ ํŠธ์˜ ๋„๋ฉ”์ธ์„ ์–ป์–ด ์—ฌ๋Ÿฌ ํ™˜๊ฒฝ์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.


2. Firebase initialize

shell command์™€ firebase initalize๊ฐ€ ์—ฐ๊ด€๋˜์–ด์žˆ์œผ๋ฏ€๋กœ ์ด ์œ„์น˜์ด๋‹ค..

firebase ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” firebase console์˜ ํ”„๋กœ์ ํŠธ์˜ ์†์„ฑ์ •๋ณด๋ฅผ ๋‚˜์˜ ์›น์•ฑ source์— ๊ฐ€์ ธ์™€์•ผํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์†์„ฑ์ •๋ณด๋ฅผ ๋‚˜์˜ source ์ฝ”๋“œ์— ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ• 2๊ฐ€์ง€๋ฅผ ์•Œ์•„๋ณด๊ฒ ๋‹ค.

ใ„ฑ. config ์ฝ”๋“œ์— ์ง์ ‘ ๋„ฃ๊ธฐ

firebase console > project Overview > ์•ฑ์ถ”๊ฐ€ > ์›น์•ฑ ์„ ํƒ

์•„๋ž˜ ์Šคํ”ผ๋„ท์ด ๋‚˜์˜ค๊ฒŒ๋œ๋‹ค. ์ด ๋‚ด์šฉ์„ ๋‚ด๊ฐ€ ํ˜„์žฌ ๊ฐœ๋ฐœํ•˜๊ณ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์˜ html ํ•˜๋‹จ์ด๋‚˜, ๊ด€๋ จ javascript code์— ์ง์ ‘ ๋„ฃ๊ฒŒ ๋˜๋ฉด, ํ•ด๋‹น html, js ํŒŒ์ผ์—์„œ๋Š” firebase ๋ณ€์ˆ˜์— ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ๋‹ค. firebase๋ณ€์ˆ˜์— ์ ‘๊ทผ์„ ํ•˜๊ฒŒ ๋˜๋ฉด firebase.auth(), firebase.database(), firebase.storage()๋“ฑ์˜ ๊ฐœ๋ฐœ ์„œ๋น„์Šค์— ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ์–ด ๋‚˜์˜ ์›น์•ฑ์— ๋งž์ถฐ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

<script src="https://www.gstatic.com/firebasejs/5.7.0/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: "APIKEY",
    authDomain: "DOMAIN",
    databaseURL: "DB URL",
    projectId: "triptmate",
    storageBucket: "BUCKET URL",
    messagingSenderId: "ID"
  };
  firebase.initializeApp(config);
</script>

ํ•˜์ง€๋งŒ ์ด ๊ฒฝ์šฐ, source code์— ๊ทธ๋Œ€๋กœ ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— html์— ๋„ฃ๊ธฐ๋ผ๋„ ํ•˜๋ฉด, F12 ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์ด์šฉํ•ด์„œ APIKEY ๋“ฑ ์ค‘์š”์ •๋ณด๋ฅผ ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ณด์•ˆ์„ ์œ„ํ•ด์„œ๋ผ๋ฉด ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ๊ถŒ์žฅํ•œ๋‹ค.

ใ„ด. shell ํ™œ์šฉํ•ด์„œ config ์ˆจ๊ธฐ๊ธฐ

๋ฐ”๋กœ htmlํƒœ๊ทธ์•ˆ์— ํ•ด๋‹น config๊ณผ ๊ด€๋ จํ•œ ์ •๋ณด๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

<script src="/__/firebase/5.5.8/firebase-app.js"></script>
<script src="/__/firebase/5.5.8/firebase-auth.js"></script>
<script src="/__/firebase/5.5.8/firebase-database.js"></script>
<script src="/__/firebase/5.5.8/firebase-storage.js"></script>
<script src="/__/firebase/5.5.8/firebase-messaging.js"></script>
<script src="/__/firebase/init.js"></script>

๋‹ค์Œ ํƒœ๊ทธ์— ์žˆ๋Š” js์˜ ๋‚ด์šฉ์€ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ์‚ฌ์šฉ์ž firebase ํ”„๋กœ์ ํŠธ์˜ ์ฃผ์š” ์ •๋ณด๋“ค์„ ๊ฐ€๋ฆฐ ํ›„ ๊ฐ service๋ฅผ initalize ํ•œ๋‹ค.

cmd์—์„œ firebase ๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•ด์„œ ์„ค์ •ํ•œ ๋‚˜์˜ firebase ํ”„๋กœ์ ํŠธ์˜ config ๊ฐ’๋“ค์ด ๋ชจ๋‘ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ์„ค์ •๋˜๊ณ , ๊ทธ ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ€ ์ € js ํŒŒ์ผ์— ๋“ค์–ด๊ฐ„๋‹ค.

firebase use --add
? Which project do you want to add? (Use arrow keys)
> friendychat-8920d
  triptmate

์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ๋‚˜์˜ firebase ํ”„๋กœ์ ํŠธ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.


3. Database ๋ฉ”์†Œ๋“œ ํ™œ์šฉ ์ •๋ฆฌ

Firebase Database์˜ ๋ฉ”์†Œ๋“œ๋ฅผ Select / Update / Insert ๋ช…๋ น์–ด๋ฅผ ์—ฐ๊ด€์‹œ์ผœ์„œ ์‚ฌ์šฉ๋ฒ•์„ ๋ถ„๋ฅ˜ํ•˜์˜€๋‹ค.

3-1. READ (select)

var callback = function(snap){
  printf("snap.val()");
}
firebase.database().ref("path").on("value", callback)
  • ํ•ด๋‹น path(๊ฒฝ๋กœ) ์•ˆ์— ์žˆ๋Š” value๋ฅผ snapshot์„ ์ฐ๋“ฏ์ด ๊ฐ€์ ธ์™€์„œ printํ•˜๋Š” source์ด๋‹ค.

**๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ• **: .on("value", callback)

  • 1๋ฒˆ์งธ argument

    • value = ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์ˆ˜์‹  ๋Œ€๊ธฐ (์ „์ฒด)
    • child_added = ํ•˜์œ„์š”์†Œ ์ถ”๊ฐ€์— ๋Œ€ํ•œ ์ˆ˜์‹  ๋Œ€๊ธฐ
    • child_changed = ํ•˜์œ„์š”์†Œ ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•œ ์ˆ˜์‹ ๋Œ€๊ธฐ
  • 2๋ฒˆ์งธ argument

    • 1๋ฒˆ์งธ argumnet์˜ ๋‚ด์šฉ๋Œ€๋กœ ๋Œ€๊ธฐํ•˜๋˜ event๊ฐ€ ๋“ค์–ด์˜ค๋ฉด callback ํ•จ์ˆ˜ ์‹คํ–‰

์ฆ‰, read๋Š” ํ•ด๋‹น path์˜ ์–ด๋Š๋ถ€๋ถ„์ด๋ผ๋„ ๋ณ€๊ฒฝ์ด ์žˆ๋‹ค๋ฉด callback์„ ์‹คํ–‰ํ•˜์—ฌ callback์—์„œ htmltag.innerhtml ๋“ฑ์˜ html๊ณผ ์—ฐ๊ด€ํ•ด์„œ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ์„ ๋ชฉ์ ์œผ๋กœ ํ•˜์˜€๋‹ค.

ํŠธ๋ž˜ํ”ฝ ์ƒ 1๋ฒˆ์งธ argument์˜ ๋Œ€๊ธฐ ๋ฒ”์œ„๋Š” ๋ณ€๊ฒฝ์‚ฌํ•ญ์˜ ์ตœํ•˜์œ„ ์œ„์น˜๊ฐ€ ์ œ์ผ ํšจ์œจ์ ์ด๋‹ค.

firebase์˜ realtime database๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š”, db ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์ˆ˜์‹ ์„ ๋Œ€๊ธฐํ•˜๊ณ  ์ด์— ๋Œ€ํ•ด ๋ฐ”๋กœ ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ๋Š” eventlistener๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

3-2. WRITE (insert)

firebase.ref("path").push({
	json1_key : json1_val,
    json2_key : json2_val
});
  • ํ•ด๋‹น path(๊ฒฝ๋กœ) ์— push์•ˆ์—์žˆ๋Š” argument๋ฅผ key๋กœ ํ•˜๋„๋ก data๋ฅผ insertํ•˜๋Š” source์ด๋‹ค.

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•: .push(json)

= ํ•ด๋‹น json์„ value๋กœ ๊ฐ–๋Š” key๋ฅผ ์ƒ์„ฑํ•˜๊ณ  push

  • json
    • { }๋ฅผ ์ด์šฉํ•ด์„œ ์—ฌ๋Ÿฌ key-value ์Œ์˜ json ๊ฐ’์„ ๋„ฃ์–ด๋„ ์ƒ๊ด€์—†๋‹ค.
    • ์ด๋•Œ ์ฃผ์˜ํ•ด์•ผํ•  ์ ์€ argument๊ฐ€ ํ•ด๋‹น ๊ฒฝ๋กœ์˜ value๋กœ ๋“ค์–ด๊ฐ„๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
    • ๊ทธ๋ ‡๋‹ค๋ฉด key๋Š”? ์ž„์˜์ƒ์„ฑ
key : random_key, value : json

์œ„ code๋ฅผ ์ ์šฉํ–ˆ์„ ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ทœ์น™์œผ๋กœ database์— ๋ฐ˜์˜๋œ๋‹ค.
path์•„๋ž˜์— ๋ฐ”๋กœ argument์˜ ๋‚ด์šฉ์ด ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.

path
  ใ„ดrandom_key2 (afdlahfkasdjka)
    ใ„ดjson1_key : json1_val
    ใ„ดjson2_key : json2_val

3-3. UPDATE (update)

firebase.ref("path").set({
	json1_key : json1_val,
    json2_key : json2_val
});
  • ํ•ด๋‹น path(๊ฒฝ๋กœ)๋ฅผ key๋กœ ํ•˜๊ณ  set์•ˆ์˜ argument๋ฅผ value๋กœ ํ•˜๋Š” data๋ฅผ insertํ•˜๋Š” source์ด๋‹ค.

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•: .set(json)

= ํ•ด๋‹น json์„ value๋กœ path๋ฅผ key๋กœํ•ด์„œ ํ•ด๋‹น key(๊ฒฝ๋กœ)์˜ ๋‚ด์šฉ์„ ๋ฎ์–ด์”Œ์šด๋‹ค

  • json
    • { }๋ฅผ ์ด์šฉํ•ด์„œ ์—ฌ๋Ÿฌ key-value ์Œ์˜ json ๊ฐ’์„ ๋„ฃ์–ด๋„ ์ƒ๊ด€์—†๋‹ค.
    • ์ด๋•Œ ์ฃผ์˜ํ•ด์•ผํ•  ์ ์€ key๊ฐ’, ์ฆ‰ ํ•ด๋‹น path์•ˆ์— ์žˆ๋˜ ๊ธฐ์กด๋‚ด์šฉ์ด .set์˜ argument๋กœ ๋Œ€์ฒด๋œ๋‹ค๋Š” ์ ์ด๋‹ค.
key : path, value : json

์œ„ code๋ฅผ ์ ์šฉํ–ˆ์„ ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ทœ์น™์œผ๋กœ database์— ๋ฐ˜์˜๋œ๋‹ค.
path์•„๋ž˜์— ๋ฐ”๋กœ argument์˜ ๋‚ด์šฉ์ด ๋“ค์–ด๊ฐ„๋‹ค

path
  ใ„ดjson1_key : json1_val
  ใ„ดjson2_key : json2_val
  

#๊ธฐ์กด๊ฐ’์ด ์–ด๋–ค๊ฒƒ์ด๋“  ์ƒ๊ด€์—†์ด ๋ฎ์–ด์”Œ์–ด์ง„๋‹ค.
(๊ธฐ์กด๊ฐ’)
path
  ใ„ดjson1_key : json1_val
  ใ„ดjson2_key : json2_val
  ใ„ดjson3_key : json3_val
  ใ„ดjson4_key : json4_val
  ใ„ดjson5_key : json5_val
  ใ„ดjson6_key : json6_val
-> ์–ด์ฐŒ๋๋“  set์˜ argument๊ฐ€ key๋กœ ์„ค์ •!

V. Page Control

1. login

๊ฒฝ๋กœ ์งง์€ ์„ค๋ช…
/(root) ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€
contoller
1. google_login page ๋„์šฐ๊ธฐ
2. google api ์ด์šฉํ•œ ๋กœ๊ทธ์ธ OAUTH
3. show log_out button
4. show chat button (./list.html)

2. Roomlist

๊ฒฝ๋กœ ์งง์€ ์„ค๋ช…
/list.html ์ฑ„ํŒ…๋ฐฉ ๋ฆฌ์ŠคํŠธ ํŽ˜์ด์ง€
contoller
firebase.database().ref('/fcmTokens').child(currentToken).set(firebase.auth().currentUser.uid);

์œ ์ € fcmtoken ์ €์žฅ

firebase.database().ref('messages/').limitToLast(12).on('value', callback);

[loadList(), displayList(roomlist)];

database์— ์žˆ๋Š” roomlist ์ „๋ถ€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฐ ๋ณด์—ฌ์ฃผ๊ธฐ ๊ฒฝ๋กœ : messages

firebase.database().ref('/status/'+getUserName()+'/location').set({
    status: clickRoom
  }).catch(function(error) {
    console.error('Error writing new message to Firebase Database', error);
  });

database์— ํ˜„์žฌ ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ฆญํ•œ room์˜ ์œ„์น˜ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ๊ฒฝ๋กœ : /status/{username}/location ์ €์žฅ๊ฒฐ๊ณผ : status : {clickRoom}


3. Chatting

๊ฒฝ๋กœ ์งง์€ ์„ค๋ช…
/main.html ์ฑ„ํŒ…๋ฐฉ ํŽ˜์ด์ง€
contoller
firebase.database().ref('/messages/'+getRoom).limitToLast(12).on('child_added', callback);
  firebase.database().ref('/messages/'+getRoom).limitToLast(12).on('child_changed', callback);

user๊ฐ€ ํด๋ฆญํ•œ room์˜ ์ฑ„ํŒ…๋ฐฉ message๋ฅผ ์ „๋ถ€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฐ ๋ณด์—ฌ์ฃผ๊ธฐ ๊ฒฝ๋กœ : messages/{currentUserRoom}

firebase.database().ref('/messages/'+getRoom).push({
    name: getUserName(),
    imageUrl: LOADING_IMAGE_URL,
    profilePicUrl: getProfilePicUrl()
  }).then(function(messageRef) {
    // 2 - Upload the image to Cloud Storage.
    var filePath = firebase.auth().currentUser.uid + '/' + messageRef.key + '/' + file.name;
    return firebase.storage().ref(filePath).put(file).then(function(fileSnapshot) {
      // 3 - Generate a public URL for the file.
      return fileSnapshot.ref.getDownloadURL().then((url) => {
        // 4 - Update the chat message placeholder with the imageโ€™s URL.
        return messageRef.update({
          imageUrl: url,
          storageUri: fileSnapshot.metadata.fullPath,
          location : address,
          time: makeTime()
        });
      });
    });
  }).catch(function(error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  });

user๊ฐ€ ์ฒจ๋ถ€ํ•œ image๋ฅผ firebase stroage์— ์˜ฌ๋ฆฌ๊ณ , ๊ทธ url์„ ์–ป์–ด user๊ฐ€ ํด๋ฆญํ•œ room์˜ ์ฑ„ํŒ…๋ฐฉ message๋กœ ์ €์žฅ ๊ฒฝ๋กœ : messages/{currentUserRom} ์ €์žฅ๊ฒฐ๊ณผ messsage_key: { โ€‹ imageurl: currnet user profile image, โ€‹ location: current user location, โ€‹ name: current user name, โ€‹ storageUri: filepath, โ€‹ time: current time }

 var callback= function(snap){
    console.log(snap.val().status);
    getRoom = snap.val().status;
    loadMessages(getRoom);
    console.log(userName);
    htmlroom.innerHTML = getRoom;
  }
  firebase.database().ref('/status/'+userName+'/location').on('value', callback)

database์— ํ˜„์žฌ ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ฆญํ•œ room์˜ ์œ„์น˜๋ฅผ ์ฐพ๋Š” function์ด๋‹ค. callbackํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ, ํ•ด๋‹น ์œ„์น˜ database์˜ snapshot์„ ์ฐ๊ณ , ํ•ด๋‹น ์œ„์น˜์˜ ๊ฐ์ข… ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋กํ•œ๋‹ค. ๊ฒฝ๋กœ:/status/{username}/location

firebase.database().ref('/status/'+getUserName()+"/bookmark").push({
    text: text,
    status: getRoom,
    time: time,
    image: output
  }, getToggle()).catch(function(error) {
    console.error('Error writing new message to Firebase Database', error);
  });

database์— ํ˜„์žฌ ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ฆญํ•œ room์˜ ์œ„์น˜์—์„œ ์„ ํƒํ•œ message๋ฅผ mypage์˜ bookmark์— ์ถ”๊ฐ€ํ•˜๊ธฐ ๊ฒฝ๋กœ: /status/{username}/bookmark ์ €์žฅ๊ฒฐ๊ณผ bookmark_key{ โ€‹ text: user click text massage โ€‹ status: room name, โ€‹ time: current time, โ€‹ image: user click image message }


4. Mypage

๊ฒฝ๋กœ ์งง์€ ์„ค๋ช…
/map.html ์œ ์ € ๋งˆ์ดํŽ˜์ด์ง€
contoller
function loadBook() {  // Loads the last 12 messages and listen for new ones.
  var callback = function(snap) {
    console.log(snap);
    var data = snap.val();
    for(var key in data){
      //  console.log(data[key]);
       displayBook(data[key]);
    }

  };
  firebase.database().ref('status/'+getUserName()+"/bookmark").on('value', callback);
}

[loadBook(), displayBook(roomlist)];

ํ˜„์žฌ user์˜ bookmark ์ •๋ณด๋ฅผ mypage์— ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ๋ฆฌ์ŠคํŠธ๋ฅผ ์ฐพ๋Š”๋‹ค. callbackํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ, ํ•ด๋‹น ์œ„์น˜ database์˜ snapshot์„ ์ฐ๊ณ , ํ•ด๋‹น ์œ„์น˜์— ์ ‘๊ทผํ•œ๋‹ค. ์œ„์น˜์— ์ ‘๊ทผํ•ด์„œ ์–ป์€ data๋ฅผ displaybook()ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ html๊ณผ ์—ฐ๋™ํ•œ๋‹ค. ๊ฒฝ๋กœ : status/{username}/bookmark


VI. About US

1. ๊ฐœ๋ฐœ์ž ์ •๋ณด

  • ๊ณ ์Šน์˜ (uiuiui629) : ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค(UI) ๋””์ž์ธ, ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ
    • uiuiui629
    • loginChatDesign : ๋กœ๊ทธ์ธ์ฐฝ, ์ฑ„ํŒ…์ฐฝ ๋””์ž์ธ(main.css ์ˆ˜์ • ๋ฐ index.css, list.html ์ถ”๊ฐ€)
    • listDesign : ์ฑ„ํŒ…๋ฐฉ list ๋””์ž์ธ(list.html, list.js ์ˆ˜์ • ๋ฐ list.css ์ถ”๊ฐ€)
    • mypagedesign : ๋งˆ์ดํŽ˜์ด์ง€ ๋””์ž์ธ(map.html, map.js ์ˆ˜์ • ๋ฐ map.css ์ถ”๊ฐ€)
    • UIdesign : header ์ˆ˜์ •, ์ฑ„ํŒ…๋ฐฉ list ๋ ˆ์ด์•„์›ƒ ์ˆ˜์ •
  • ๊น€๋ฏผ์ • (mjung1798) : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ, ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ
    • ming : login ๋ถ„๋ฆฌํ•˜๊ธฐ, ๋ธŒ๋žœ์น˜ ์ •๋ฆฌ, apply .gitignore
    • ming123 : ์ฑ„ํŒ…๋ฐฉ list ๊ฐœ๋ฐœ(list.html, list.js ์ถ”๊ฐ€), icon ์ˆ˜์ •
    • Listlink : list์˜ ๊ธฐ๋Šฅ์— ๋งž๊ฒŒ db ์—ฐ๊ฒฐ, user๊ฐ€ ์œ„์น˜ํ•˜๋Š” room์ธ status DB ์žฌ๊ตฌ์„ฑ
    • roomname : DB์—์„œ ๋ถˆ๋Ÿฌ์˜จ room list์˜ ์ •๋ณด๋ฅผ html์— ๋ณด์—ฌ์ฃผ๊ธฐ (js์™€ html ์—ฐ๋™)
    • mapinformation : ๋ถ๋งˆํฌ ๋ฒ„ํŠผ ์ถ”๊ฐ€ํ•˜๊ณ , ์œ ์ €์˜ bookmark๋งŒ ๋ชจ์€ DB ์žฌ๊ตฌ์„ฑ ๋ฐ ์ €์žฅ
    • debugging : ๋ถ๋งˆํฌ๊ฐ€ ์ง€์›Œ์ง€๋Š” ํ˜„์ƒ (push์™€ set ์ฐจ์ด์  ๋ฐœ๊ฒฌ), DB ์ €์žฅ ์˜ค๋ฅ˜ ์ˆ˜์ •
    • snackbar : ๋ถ๋งˆํฌ ์ €์žฅ์‹œ snackbar ๋‚˜ํƒ€๋‚˜๊ฒŒ ์ˆ˜์ •
    • final, tripmate.V.1.0 : deploy๋ฅผ ์œ„ํ•œ ์ตœ์ข…์ ์ธ ์ „์ฒด ์ˆ˜์ •
  • ์‹ฌ์ •๋ฏผ (jmini1234) : ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ, ์ง€๋„api, firebase ์—ฐ๋™, ํ˜„์žฌ ์œ„์น˜ ๋ฐ˜ํ™˜
    • Shim
    • roomlist : ์ฑ„ํŒ…๋ฐฉ ์ƒ์„ฑ ๋ฐ ๋ถ„๋ฆฌ
    • MapApi : google map api ์™€ firebase ์—ฐ๋™ํ•˜๊ธฐ
    • converting : ํ˜„์žฌ ์œ„์น˜ ๋ฐ˜ํ™˜ ํ›„ , ์œ„๋„ ๊ฒฝ๋„๋ฅผ ์ฃผ์†Œ๋กœ ๋ณ€ํ™˜

2. ํ˜‘์—… ๊ณผ์ •

git branch๋ฅผ ์ด์šฉํ•ด์„œ ๊ธฐ๋Šฅ์„ ์ˆ˜์ •ํ•˜๊ณ , pull request๋ฅผ ์ด์šฉํ•ด์„œ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ํ™•์ธํ•˜๊ณ , conflict๋ฅผ ๋Œ€์ฒ˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ