ALL. TRIPMATE - jmini1234/tripmate GitHub Wiki
ํธ๋ฆฝ๋ฉ์ดํธ ์ฑํ ์น https://triptmate.firebaseapp.com
'๊ณํ' ์์ฃผ์ ์ฌํ ์ดํ์ ํํํ๋ค!
๊ฐ์ ์ง์ญ, ๋์๊ฐ๋๋ฅผ ํจ๊ป ์ฌํํ๋ ์ฌ๋๋ค๊ณผ ์ค์๊ฐ ์ฑํ ์ ํจ์ผ๋ก์จ, ํด์ ํ๋ ๊ฐ๊ฒ, ์ธ์ผ์ ๋ณด, ๋๋ก ์ ๋ณด ๋ฑ๋ฑ ๋ ๋ง๋ค ๋ฐ๋๋ ์ ๋ณด๋ฅผ ์ป์ด ์๋ก์ ์ฌํ์ ์พ์ ํ๊ฒ ๋ง๋๋ ์๋น์ค!
๊ฐ์ ์ง์ญ, ๋์๊ฐ๋๋ฅผ ํจ๊ป ์ฌํํ๋ ์ฌ๋๋ค๊ณผ ์ค์๊ฐ ์ฑํ ์ ํจ์ผ๋ก์จ ๊ถ๊ธํ ์ ์ ๋ฐ๋ก๋ฐ๋ก ๋ฌป๊ณ ๋ตํ๋ฉฐ ํ์ฌ ์ํฉ์ ๋ง๋ ์ ๋ณด๋ฅผ ์ฆ๊ฐ ์ ์ ์๊ณ , ๊ณํํ ์ฌํ์ ๋ณ์๋ฅผ ์ต๋ํ ์ค์ด๋๋ก ๋์๋๋ฆฝ๋๋ค.
๋ํ ์ฌํ์ง์ ์๋ ์ฌ๋ ๊ฐ์ ๊ฒฝ์ฐ, ํ์ฌ ์ฌํํ๊ณ ์๋ ์ฌ๋๋ค์ ์ค์๊ฐ ์ ๋ณด๋ฅผ ๋ด์ผ๋ก์จ ์์ ์ ์ฌํ์ ๊ณํํ๋๋ฐ ์ฐธ๊ณ ํ ์ ์์ต๋๋ค.
๋น์ฅ ๋ด์ผ, ํ๋ฌ ํ์ ์ฌํ ๊ณํ์ ์ ์ฉํ ์์๊ฐ ์๋ค๋ฉด ๋ถ๋งํฌ๋ฅผ ํตํด ๋ง์ดํ์ด์ง์ ์ ์ฅํ์ฌ, ๋ด ๊ณํ์ ์ฐธ๊ณ ํ ์ ์์ต๋๋ค.
์ฑํ ์ ์ด์ฉํ ์ฌํ์ง ์ ๋ณด ๊ฐ์ ๊ฒฝ์ฐ ๋ฐ์ ์์ ์์น์ ๋ณด๋ฅผ ํ์ธํ์ฌ ๋ฉ์ธ์ง์ ์ ๋ขฐ์ฑ์ ์์ ์๊ฐ ํ๋จํ ์ ์์ต๋๋ค.
ํธ๋ฆฝ๋ฉ์ดํธ ์ฑํ ์น https://triptmate.firebaseapp.com
๋ก๊ทธ์ธ ๋ฒํผ์ ๋๋ฅด๋ฉด ๊ตฌ๊ธ๊ณผ ์ฐ๋ํด์ ๋ก๊ทธ์ธ์ ํ ์ ์๋ค.
GO CHAT ๋ฒํผ์ ๋๋ฅด๋ฉด ์ฑํ ๋ฐฉ์ ์ ์ฅ ํ ์ ์๋ค.
์ ๋ณด๋ฅผ ์ป๊ณ ์ํ๋ ์ฑํ ๋ฐฉ์ ์ ํํ๋ค.
๊ฐ ์ฑํ ๋ฐฉ๋ง๋ค ๊ทธ ๋๋ผ์ ์ ๋ณด๋ฅผ ๊ฐ์ง ์ฑํ ๋ค์ด ๋ค์ด์๋ค.
์ ๋ณด์ ์ ๋ขฐ์ฑ์ ์ํด ์ฑํ ์ ์ด ์ฌ๋์ ์์น์ ๋ ์ง๊ฐ ์ค๋ฅธ์ชฝ ํ๋จ์ ์ถ๋ ฅ๋๋ค.
ํ์ฌ ์์น์ ๊ฐ์ด ๋์ฌ์๋ ๋ฒํผ์ ๋ถ๋งํฌ , ์ ์ฅ ๊ธฐ๋ฅ์ด๋ค. ๋ถ๋งํฌ๋ฅผ ๋๋ฅด๋ฉด ๋ง์ดํ์ด์ง์ ํด๋น ์ฑํ ์ ๋ณด๊ฐ ๋ค์ด๊ฐ ์๋ค.
์๋จ ์ค๋ฅธ์ชฝ์ ๊ณ์ ์ ๋ณด๊ฐ ์๋ ๊ณณ์ ๋๋ฅด๋ฉด ๋ง์ดํ์ด์ง๋ก ์ด๋ํ๋ค.
์ ๋ฐ์ ์ธ ๋ง์ดํ์ด์ง ํ๋ฉด์ ๋ค์๊ณผ ๊ฐ๋ค.
์ฌ์ฉ์๊ฐ ์๋ ๊ณณ์๋ํ ์ ๋ณด๋ฅผ ๊ตฌ๊ธ Map์ ํตํด ์๋ ค์ค๋ค.
๋ถ๋งํฌ ์ธ์ ์๋ ์ฌ์ฉ์๊ฐ ๋ถ๋งํฌ ๋ฒํผ์ ๋๋ ๋ ์ฑํ ์ ๋ด์ฉ๊ณผ ๊ทธ ์ฑํ ๋ฐฉ์ ์ ๋ณด๊ฐ ์ฐ์ฌ์๋ค.
![](https://user-images.githubusercontent.com/37237145/50137304-251a8100-02de-11e9-8a58-0d6bab21119c.png)
![](https://user-images.githubusercontent.com/37237145/50137369-4aa78a80-02de-11e9-9c05-8c8e9017f5f8.png)
![](https://user-images.githubusercontent.com/37237145/50137418-6f036700-02de-11e9-8bce-1d5be57bffae.png)
![](https://user-images.githubusercontent.com/37237145/50137942-277dda80-02e0-11e9-8d7d-45eaf2b15497.png)
![](https://user-images.githubusercontent.com/37237145/50138244-4af55500-02e1-11e9-9f4e-b74d65b0ebc6.png)
![](https://user-images.githubusercontent.com/37237145/50140381-e689c400-02e7-11e9-8404-57d05d295125.png)
์ผ๋ฐ์ ์ธ 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"
}
},
...
}
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
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 ์์ ์์ ๋ด์ฉ์ ' ' ์์ ๋ด์ฉ์ผ๋ก ๋ณ๊ฒฝํ๋ค.
<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๋ฅผ ์ง์ ํ๋ค.
.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 ์ ํ์๋ฅผ ์ด์ฉํ์ฌ ์ฌ๋ฌ ์์๋ค์ ์ธ๋ถ์ ์ธ ์์น, ํฌ๊ธฐ, ์ฌ๋ฐฑ ๋ฑ์ ๋์์ธ์ ์ ์ฉํ๋ค.
๋ฏธ๋์ด์ฟผ๋ฆฌ๋ฅผ ์ด์ฉํ์ฌ ๋ฐ์ํ ๋์์ธ์ ์ ์ฉํ๋ค.
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 : ์์น๋ฅผ ์๋์ ๊ฒฝ๋๋ก ๋ํ๋ธ๋ค.
// 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 ์ฐธ์กฐ) ํจ์๋ฅผ ๋ถ๋ฌ์์ ์ค์ ์ฃผ์ ๊ฐ๊น์ง ๋ฐํํ๋ค.
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๋ฅผ ํ์ํ๋ค.
<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๋ฅผ ํตํด์ ๋ฃ์ด์ค๋ค.
<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๋ฅผ ์ถ๊ฐํ๋ค.
์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ Firebase Service 4๊ฐ์งAuthentication, Database, Storage, Hosting
๋
๊ฐ๊ฐ์ ์ค์ ์ ๋ชจ๋ console์์ ํ ํ์ ์ฌ์ฉํ ์ ์๋ค.
๊ฐ develop ํ๊ฒฝ์ค์ ์ ์ฃผ์์ ๊ณผ ๊ณตํต์ ์ธ ์ฌ์ฉ๋ฒ์ ์์๋ณด์.
ํ๊ฒฝ์ค์ : 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;
ํ๊ฒฝ์ค์ : 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 ๋ฉ์๋ ํ์ฉ ์ ๋ฆฌ) ์์ ์์ธํ ๋ด์ฉ์ ํ์ธํ์.
ํ๊ฒฝ์ค์ : 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)
ํ๊ฒฝ์ค์ : ํ์ฌ ๊ฐ๋ฐ์ค์ธ 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๋ฅผ ํ์ฌ ํ๋ก์ ํธ์ ๋๋ฉ์ธ์ ์ป์ด ์ฌ๋ฌ ํ๊ฒฝ์์ ํ๋ก์ ํธ๋ฅผ ์คํํ ์ ์๋ค.
shell command์ firebase initalize๊ฐ ์ฐ๊ด๋์ด์์ผ๋ฏ๋ก ์ด ์์น์ด๋ค..
firebase ํ๋ก์ ํธ๋ฅผ ๊ฐ๋ฐํ๊ธฐ ์ํด์๋ firebase console์ ํ๋ก์ ํธ์ ์์ฑ์ ๋ณด๋ฅผ ๋์ ์น์ฑ source์ ๊ฐ์ ธ์์ผํ๋ค. ๋ฐ๋ผ์ ์์ฑ์ ๋ณด๋ฅผ ๋์ source ์ฝ๋์ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ 2๊ฐ์ง๋ฅผ ์์๋ณด๊ฒ ๋ค.
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 ๋ฑ ์ค์์ ๋ณด๋ฅผ ์ฝ๊ฒ ์ ๊ทผํ ์ ์๋ค๋ ๋ฌธ์ ๊ฐ ์๋ค. ๋ฐ๋ผ์ ๋ณด์์ ์ํด์๋ผ๋ฉด ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ๊ถ์ฅํ๋ค.
๋ฐ๋ก 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 ํ๋ก์ ํธ๋ฅผ ์ค์ ํ ์ ์๋ค.
Firebase Database์ ๋ฉ์๋๋ฅผ Select / Update / Insert ๋ช ๋ น์ด๋ฅผ ์ฐ๊ด์์ผ์ ์ฌ์ฉ๋ฒ์ ๋ถ๋ฅํ์๋ค.
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๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ง๋ค์ด์ก๊ธฐ ๋๋ฌธ์ด๋ค.
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
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๋ก ์ค์ !
๊ฒฝ๋ก | ์งง์ ์ค๋ช |
---|---|
/(root) | ๋ก๊ทธ์ธ ํ์ด์ง |
1. google_login page ๋์ฐ๊ธฐ
2. google api ์ด์ฉํ ๋ก๊ทธ์ธ OAUTH
3. show log_out button
4. show chat button (./list.html)
๊ฒฝ๋ก | ์งง์ ์ค๋ช |
---|---|
/list.html | ์ฑํ ๋ฐฉ ๋ฆฌ์คํธ ํ์ด์ง |
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}
๊ฒฝ๋ก | ์งง์ ์ค๋ช |
---|---|
/main.html | ์ฑํ ๋ฐฉ ํ์ด์ง |
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 }
๊ฒฝ๋ก | ์งง์ ์ค๋ช |
---|---|
/map.html | ์ ์ ๋ง์ดํ์ด์ง |
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
- ๊ณ ์น์ (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 : ํ์ฌ ์์น ๋ฐํ ํ , ์๋ ๊ฒฝ๋๋ฅผ ์ฃผ์๋ก ๋ณํ
git branch๋ฅผ ์ด์ฉํด์ ๊ธฐ๋ฅ์ ์์ ํ๊ณ , pull request๋ฅผ ์ด์ฉํด์ ๋ณ๊ฒฝ์ฌํญ์ ํ์ธํ๊ณ , conflict๋ฅผ ๋์ฒํ์ต๋๋ค.