全端勇士之路 Node.js 基礎學習-結合 Firebase + Express 做一個小應用(2)

前言

在前面已經確定我們的 Express 正確的接上 Firebase 之後,就來試著來加入新增的功能看看

建立 UI 介面 & Route

首先我們要先建立一下 UI 介面,由於我將 firebase 放置在 /route/users 的首頁,所以就要去建立一個 user.ejs 內容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text" id="content" name="content">
<input type="button" id="btn" value="送出">
<ul id="list">

</ul>
<script src="../javascripts/all.js"></script>
</body>
</html>

然後 /route/users 的部分要修改一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var express = require('express');
var router = express.Router();
var firebaseAdmin = require('../connection/firebase-admin');

/* GET users listing. */
router.get('/', function(req, res, next) {
res.render('user');
});

router.post('/create', function(req, res, next) {
console.log(req.body);
res.send('傳送成功')
res.end();
});

module.exports = router;

這樣畫面就會出來了

畫面出現

修改 Route 接上 Firebase

這邊我會使用 AJAX 的方式,但是這邊有一個雷點注意,目前 Node.js 不支援 fetch API,所以必須使用 XHR 或是其他套件的作法

接下來我在 public/javascripts 底下建立 all.js 檔案,並且內容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var content = document.getElementById('content');
var btn = document.getElementById('btn');
var list = document.getElementById('list');

function XHRAJAX () {
var xhr = new XMLHttpRequest();
xhr.open('POST','/users/create')
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
var test = 'content=' + content.value;
xhr.send(test); // 透過組字串方式傳入
xhr.onload = function () {
var _data = xhr.responseText;
console.log(_data);
}
}

btn.addEventListener('click', XHRAJAX)

此時在頁面上輸入內容,就可以看到回傳的資料哩

回傳的資料

這樣可以確保資料真的有被 route 給接收到,這樣子我們才可以一步一步往下開發

Firebase 新增語法

接下來將會使用新增的語法來建立資料,所以這邊來修改一下 route

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var express = require('express');
var router = express.Router();
var firebaseAdmin = require('../connection/firebase-admin');

/* GET users listing. */
router.get('/', function(req, res, next) {
res.render('user');
});

router.post('/create', function(req, res, next) {
var fireRef = firebaseAdmin.ref('todo').push(); // 設定路徑,並使用 push() 確保唯一值
fireRef.set(req.body)
res.send('傳送成功')
res.end();
});

module.exports = router;

接下來就可以直接輸入 npm start 並於畫面上輸入送出,如果成功的話 firebase 就會新增一筆資料像這樣子

新增資料

由於傳過來的資料是 { content: 123 },所以才將整個物件丟進去,但是正確做法應該要這樣子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var express = require('express');
var router = express.Router();
var firebaseAdmin = require('../connection/firebase-admin');

/* GET users listing. */
router.get('/', function(req, res, next) {
res.render('user');
});

router.post('/create', function(req, res, next) {
var fireRef = firebaseAdmin.ref('todo').push(); // 設定路徑,並使用 push() 確保唯一值
var data = {
content: req.body.content
}
fireRef.set(data)
res.send('傳送成功')
res.end();
});

module.exports = router;

這樣寫才能夠避免一些非必要的欄位被傳入

新增資料

顯示資料

那麼當我們新增完畢資料後希望可以顯示在畫面上呢?那就這樣寫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
router.post('/create', function(req, res, next) {
var fireRef = firebaseAdmin.ref('todo').push(); // 設定路徑,並使用 push() 確保唯一值
var fireGetRef = firebaseAdmin.ref('todo')
var data = {
content: req.body.content
}
fireRef.set(data).then(()=> {
fireGetRef.on((snapshot) => {
var listData = snapshot.val();
res.send({
'status': true,
'result': listData,
'massage': '新增資料成功'
});
})
})
});

(前後略過,code太長)

接下來修改一下 all.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var content = document.getElementById('content');
var btn = document.getElementById('btn');
var list = document.getElementById('list');

function XHRAJAX () {
var xhr = new XMLHttpRequest();
xhr.open('POST','/users/create')
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
var test = 'content=' + content.value;
xhr.send(test);
xhr.onload = function () {
var _data = xhr.responseText;
showTodo(JSON.parse(_data));
}
}

function showTodo (data) {
if(data.success) {
var listAjax = data.result
for(item in listAjax) {
var str = document.createElement('li');
str.textContent = listAjax[item].content;
list.appendChild(str);
}
} else {
return
}
}

btn.addEventListener('click', XHRAJAX)

這樣子就可以在畫面上顯示資料哩~

uploading...

但是我這邊建議使用 innerHTML 因為使用 createElement 有可能會發生重複顯示問題

1
2
3
4
5
6
7
8
9
10
11
12
function showTodo (data) {
if(data.success) {
var listAjax = data.result
var str = '';
for(item in listAjax) {
str += '<li>'+ listAjax[item].content + '</li>'
}
list.innerHTML = str;
} else {
return
}
}

這樣子可以確保每一次新增資料的時候畫面都是最新的