專案建立
首先直接輸入 express --view=ejs
快速產生資料夾結構
取得 Firebase 服務
建立一個新的 Firebase 資料庫後,進入資料庫設定點選 服務帳戶
,會看到下方有 Admin SDK
的使用方法,並且複製程式碼。
最重要的是點選最下方的 產生新的私密金鑰
,此檔案為一個 JSON 檔,內容稍後會用到。
安裝套件
這裡除了要安裝 Firebase admin
的套件外,還需安裝 dotenv
這個環境變數套件。
先附上兩個套件的官方文件
firebase-admin github
firebase-admin npm
dotenv github
dotenv npm
來說說為什麼要 dotenv
這個套件吧!
- 上一步下載回來的金鑰是一個
express-todolist-firebase-adminsdk-02zaz-3d9472adf6.json
這種形式的檔案,其內容包含以下資訊:當然你可以將整個檔案重新命名並參考官方的引入方式,上一步複製程式碼區塊的地方1
2
3
4
5
6
7
8
9
10
11
12{
"type": "xxx",
"project_id": "xxx",
"private_key_id": "xxx",
"private_key": "xxx",
"client_email": "xxx",
"client_id": "xxx",
"auth_uri": "xxx",
"token_uri": "xxx",
"auth_provider_x509_cert_url": "xxx",
"client_x509_cert_url": "xxx"
}不過也能透過1
var serviceAccount = require("path/to/serviceAccountKey.json");
環境變數
的方式引入,更為簡潔,畢竟一個專案可能會有很多服務,每個都一個一個引入不是很好。 - 如果是一個服務就引入一個檔案的話,為了不上到版控,就必須不斷修改
.gitignore
的內容,而採用環境變數的方式就完全不需要在版控額外增加忽略的檔案
說明完理由就直接輸入指令吧
1 | npm install --save dotenv firebase-admin |
相關檔案建立
- 在
根目錄
新增.env
檔案,並根據私密金鑰
的內容填入。
注意: 這裡的的雙引號可加可不加,但FIREBASE_PRIVATE_KEY
一定要加,不然100%
報錯,因為內容含有特殊符號
,詳細規則可參照以下官方說明
dotenv#rules
關於FIREBASE_PRIVATE_KEY
加雙引號的寫法在部屬到 heroku 時會有問題,所以這邊就不加雙引號了。
但必須在引入的時候注意寫法,以下有提供範例程式碼1
2
3
4
5
6
7
8
9
10
11FIREBASE_DATABASEURL=xxx
FIREBASE_TYPE=xxx
FIREBASE_PROJECT_ID=xxx
FIREBASE_PRIVATE_KEY_ID=xxx
FIREBASE_PRIVATE_KEY=xxx
FIREBASE_CLIENT_EMAIL=xxx
FIREBASE_CLIENT_ID=xxx
FIREBASE_AUTH_URL=xxx
FIREBASE_TOKEN_URL=xxx
FIREBASE_AUTH_PROVIDE_X509_CERT_URL=xxx
FIREBASE_CLIENT_X509_CERT_URL=xxx - 在
根目錄
新增plugins
資料夾並創建一支firebase-admin.js
,名稱隨你命名,只要最後路徑對就好
註:private_key
的寫法會不太一樣,原本應該是process.env.FIREBASE_PRIVATE_KEY
,必須修改成process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n')
,這樣部屬 heroku 才不會有問題。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25const firebaseAdmin = require('firebase-admin');
// 引入 dotenv 檔
// process.env.變數名稱 指向 .env 中的 變數名稱
require('dotenv').config();
// 跟官方引入是一樣的,不過我們使用變數的方式
firebaseAdmin.initializeApp({
credential: firebaseAdmin.credential.cert({
type: process.env.FIREBASE_TYPE,
project_id: process.env.FIREBASE_PROJECT_ID,
private_key_id: process.env.FIREBASE_PRIVATE_KEY_ID,
private_key: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'),
client_email: process.env.FIREBASE_CLIENT_EMAIL,
client_id: process.env.FIREBASE_CLIENT_ID,
auth_uri: process.env.FIREBASE_AUTH_URL,
token_uri: process.env.FIREBASE_TOKEN_URL,
auth_provider_x509_cert_url: process.env.FIREBASE_AUTH_PROVIDE_X509_CERT_URL,
client_x509_cert_url: process.env.FIREBASE_CLIENT_X509_CERT_URL,
}),
databaseURL: process.env.FIREBASE_DATABASEURL,
});
const db = firebaseAdmin.database();
// 輸出模組給外部 router 使用
module.exports = db;
引入服務
來到 routes
中的 index.js
,引入 Firebase 服務
1 | const express = require('express'); |
開啟服務 npm start
後輸入 http://localhost:3000/
,假使 CMD
有回傳以下物件陣列格式就以正確接上!!
前端模版建立
來到 public
中的 index.ejs
,並參考以下範例模版
註: 這裡我有引用 axios
的 CDN 服務,方便稍後撰寫 AJAX 更為簡潔,畢竟原生的 xhr
寫法在先前已經有提到過了,就不再贅述。
1 |
|
後端製作 post API
利用 Express 快速建立 API,並搭配 Firebase 存儲前端傳過來的資料。
在 routes
中的 index.js
加入以下範例代碼段落:
1 | router.post('/addTodo', function(req, res, next) { |
由於 Firebase 回傳的是物件格式,在迴圈上必須使用 for in
寫法,而不是 forEach()
。
本人不是很喜歡 for in
在去組字串(ex:data[i]),所以使用 forEach()
將同一份資料包在物件內,並回傳前端一個 陣列
格式。
前端串接資料
後端已經開好 API 了,接下來就在前端提取輸入內容再利用 AJAX 傳進後端
隨後,後端與資料庫將會寫入資料並回傳 response
給前端做渲染
在 public/javascripts
中建立 all.js
,並可參考以下程式碼:
1 | // DOM 宣告 |
此處會使用 data-key
來保存唯一值,因為刪除功能時會需要這個唯一值跟 Firebase 刪除資料。
依照以上操作,已經可以開啟 http://localhost:3000/
輸入一些代辦事項,並渲染出來。
接下來會介紹如何在 進頁面
時就跟資料庫取得資料並渲染代辦事項以及刪除代辦事項。
後端修正 get API
進站時的路由是 /
,所以就必須修改 routes/index
中的 router.get('/')
。
修改範例請參照以下程式碼:
1 | router.get('/', function(req, res, next) { |
模版修改
一開始進站就要渲染的話必須先將 DOM 結構寫出,在根據後端 GET 進來的資料做 forEach()
渲染資料列表。
修改位置 index.ejs
中的 ul
,可參照以下範例:
1 | <ul class="todoList"> |
完成以上修正後,已經可以在進入首頁後看到資料顯示。
接下來就是最後的刪除部分囉,一起加油吧!!
後端新增 delete API
刪除 API 的路由是 /deleteTodo
,在 routes/index
中新增 router.delete('/deleteTodo')
。
修改範例請參照以下程式碼:
1 | router.delete('/deleteTodo', function(req, res) { |
前端模版修正
多了刪除功能,代表也要有按鈕綁定事件。所以模版也需要一併修正
1 | <ul class="todoList"> |
前端串接刪除資料
在 all.js
中加入刪除功能
1 | todoList.addEventListener('click', deleteTodo); |
終於完成最簡易的前後端串接代辦清單啦!!