CHAPTER 23 - 串接 Firebase 做「陌生人聊天」 App
看完了前面幾篇,有沒有感受到 EZoApp 的強大呢?EZoApp 可以串 JSON、新聞、Google 試算表、氣象、政府開放資料、Picasa、Flickr…….,現在再來介紹更強大的用法:讓 EZoApp 串起 Firebase 的服務,做一個簡單的即時聊天室。
完成範例:http://jqmdesigner.appspot.com/designer.html#&ref=6244329743974400
廢話不多說,直接連上 Firebase 的官網瞧瞧 ( https://www.firebase.com/ )
同樣的,先註冊一個帳號起來
完成之後 Firebase 就會直接先給你一個專案,專案名稱待會會用到
註冊步驟完成之後呢,Firebase 有提供了一個五分鐘快速上手的介紹,藉由這個快速上手,我們也可以五分鐘之內把 Firebase 和 EZoApp 串起來。
前置作業,先在 EZoApp 的 JS 編輯區域寫上這一些程式碼,目的在於可以確保外部 JS 載入之後在進行動作,因此這裡必須使用 loadJS 的方式,如果不會用也沒關係,複製這段程式碼貼上去,loadJS 就是載入外部的 JS,裡頭就放入載完 JS 才會執行的 function 即可。
( 範例:http://jqmdesigner.appspot.com/designer.html#&ref=6210073353256960 )
(function (document, $) {
$(document).on('pageinit', '#home', function () {
loadJS('https://cdn.firebase.com/js/client/1.1.1/firebase.js', function () {
// 待會要串接的程式碼
});
});
function loadJS(src, callback) {
var head = document.getElementsByTagName("head")[0],
script = document.createElement('script');
script.src = src;
script.onload = callback;
script.onerror = function (e) {
alert("failed: " + JSON.stringify(e));
};
head.appendChild(script);
head.removeChild(script);
}
}(document, jQuery));
再來按照 Firebase 的五分鐘實作來玩一玩,按照步驟一一做下去,在 EZoApp 的 JS 面板練習。
完成之後你會發現你的 JS 程式碼應該長這樣:
HTML:
<div id="messagesDiv">
<input type="text" id="nameInput" placeholder="Name">
<input type="text" id="messageInput" placeholder="Message">
</div>
javascript:
var myDataRef = new Firebase('https://shining-torch-42.firebaseio.com/');
$('#messageInput').keypress(function (e) {
if (e.keyCode == 13) {
var name = $('#nameInput').val();
var text = $('#messageInput').val();
myDataRef.push({
name: name,
text: text
});
$('#messageInput').val('');
}
});
myDataRef.on('child_added', function (snapshot) {
var message = snapshot.val();
displayChatMessage(message.name, message.text);
});
function displayChatMessage(name, text) {
$('<div/>').text(text).prepend($('<em/>').text(name + ': ')).appendTo($('#messagesDiv'));
$('#messagesDiv')[0].scrollTop = $('#messagesDiv')[0].scrollHeight;
};
點選 preview 就可以開始輸入名字和訊息,按下 enter 就會發送出去,而且所有人會即時收到,立馬完成一個即時通訊的 App ( 點選 preview 預覽測試: http://jqmdesigner.appspot.com/designer.html#&ref=6282244440195072 )
回過頭來看一下 Firebase 的資料庫結構,可以發現完全是 json 的樣子
可以運作之後,再來就是要做一下美化,先把 input 放到 footer 的地方,HTML 就變成這樣:
<div id="home" data-role="page">
<div data-role="header" data-position="fixed" data-theme="b">
<h3>陌生人聊天室</h3>
</div>
<div role="main" class="ui-content">
<div id="messagesDiv"></div>
</div>
<div id="footer" data-role="footer" data-position="fixed" data-theme="b">
<input type="text" id="nameInput" placeholder="Name">
<input type="text" id="messageInput" placeholder="Message">
</div>
</div>
然後利用再改一下 JS,目標是要讓自己輸入的對話框在右邊,別人的在左邊,而且自己的對話框顏色會和別人的不同,方法就是先讀取當下的時間作為 id,並將這組 id 存入 Firebase,如果每次出來 id 相同,就表示是自己的對話框,再利用 CSS 的方式讓對話框在右邊就好囉!
所以 JS 會長這樣:
(function (document, $) {
var now = new Date;
var genid = "id_gen_" + now.getTime(); // 利用時間作為 id 就不容易重複
$(document).on('pageinit', '#home', function () {
loadJS('https://cdn.firebase.com/js/client/1.1.1/firebase.js', function () {
var myDataRef = new Firebase('https://shining-torch-42.firebaseio.com/');
$('#messageInput').keypress(function (e) {
if (e.keyCode == 13) {
var userid = genid;
var name = $('#nameInput').val();
var text = $('#messageInput').val();
myDataRef.push({
name: name,
text: text,
userid: userid // 增加一個 id
});
$('#messageInput').val('');
}
});
myDataRef.on('child_added', function (snapshot) {
var message = snapshot.val();
displayChatMessage(message.name, message.text, message.userid);
});
function displayChatMessage(name, text, userid) {
$('#messagesDiv').prepend(
'<div class="' + userid + '">' +
'<div class="message">' + text + '</div>' +
'<div class="name">' + name + '</div>' +
'</div>'
);
if (userid == genid) {
$('.' + userid).addClass('me'); // id 相同就是自己
}
};
});
});
function loadJS(src, callback) {
var head = document.getElementsByTagName("head")[0],
script = document.createElement('script');
script.src = src;
script.onload = callback;
script.onerror = function (e) {
alert("failed: " + JSON.stringify(e));
};
head.appendChild(script);
head.removeChild(script);
}
}(document, jQuery));
CSS:
html{
height:100%;
}
body{
background:url('https://dl.dropboxusercontent.com/u/59597657/test/img/testbg20141022.jpg');
background-size:cover;
background-attachment: fixed;
height:100%;
}
div[data-role="page"],.ui-content{
background:rgba(0,0,0,0);
}
#footer{
box-sizing:border-box;
padding:0 10px;
}
.name{
width:100%;
text-align:left;
font-size:12px;
color:#fff;
text-shadow:#000 0 0 5px,#000 0 0 2px;
margin:10px 0 10px 10px;
}
.me .name{
color:#ff5;
text-align:right;
margin:10px 15px 10px 0;
}
.message{
text-shadow:none;
box-sizing:border-box;
width:100%;
padding:10px 20px;
border-radius:10px;
margin-bottom:15px;
background:rgba(255,255,255,.6);
position:relative;
color:#000
}
.message::before{
content:'';
width:0;
height:0;
position:absolute;
bottom:-20px;
left:15px;
border-width:10px 7px;
border-style:solid;
border-top-color:rgba(255,255,255,.6);
border-left-color:rgba(0,0,0,0);
border-right-color:rgba(0,0,0,0);
border-bottom-color:rgba(0,0,0,0);
}
.me .message{
background:rgba(255,255,150,.6);
}
.me .message::before{
border-top-color:rgba(255,255,150,.6);
left:auto;
right:15px;
}
完成範例,點選 preview 預覽:http://jqmdesigner.appspot.com/designer.html#&ref=6215586547761152