[推薦] Backend as a service 服務 – Firebase (Web 篇)

平常在開發 Web 程式或是 mobile 程式時都會需要後端的 API 支援,比較常的做法自行建立一個後端 Server,但是假如所要開發的功能非常陽春,例如使用到的 API 只有簡單的登入並且資料儲存,自己建立一個又有點麻煩,這時候就可以選擇 Backend as a service 服務,Backend as a service 的好處就是無需要寫程式碼實作功能,本身就提供一些基本功能供使用者使用,本篇將介紹最多人使用且有免費額度的 Backend as a service 服務 Firebase

基本介紹

官方網站:https://firebase.google.com/

Firebase 文件 (WEB):https://firebase.google.com/docs/web/setup

Firebase 目前是一個被 Google 收購的服務,目前因為其中的推播功能 (Cloud Messaging) 是不用錢的,且使用起來非常簡單,所以非常多的 APP 廠商都會使用 Firebase 來處理推播,而本篇要介紹的是使用 firebase 來當簡易的網頁後端 API 來進行登入基本的資料儲存

備註:這邊程式碼只有簡單帶過,詳細功能請參考官方文件

建立專案

首先進入 Firebase 的 console 頁面 https://console.firebase.google.com,點「新增專案按鈕」

接著會要求輸入專案的名稱

並且詢問是否啟用 Google Analytics

這邊就依據自己的情況選擇是否開啟

接著等待專案建立完成

建立應用程式

專案建立完成時,會需要建立應用程式

而本篇是要使用 Web 應用程式,所以點選 Web 的 Icon

輸入自己想要的應用程式名稱

等待應用程式建立完成後,就會有新增 Firebase SDK 的指南

目前有兩種選擇,一種是使用 npm 安裝的版本,另外一種是使用 CDN 模組化的版本,可依據自己的情況做選擇

下面有程式碼範例,其中包括自己專案的相關設定參數,可以直接複製使用

使用 Firebase 各項服務

Authentication

Authentication 提供了各種平台做帳號註冊、登入、換密碼、忘記密碼… 等的功能,其中忘記密碼與重設密碼也做到了包括寄信給使用者的機制,非常方便

在側邊工具列點 Authentication 就能進入頁面

接這點「開始使用」

接著會出現可選擇使用哪些登入方式,其中包括了 Google, Facebook … 等第三方平台,這些需要輸入自己在該平台的開發者專案 key 與 id,這邊使用簡易的「電子郵件/密碼」與「Google」做簡易的 demo

信箱驗證

點左邊的「電子郵件/密碼」

接著點「啟用」,「電子郵件連結」部分則依據自己情況看是否使用

並且可以在 Template 頁面設定,重設密碼或是驗證信的內容

接著就可以在程式中使用註冊與登入功能

import { initializeApp } from "firebase/app";
import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword } from "firebase/auth";

const firebaseConfig = {
  // ... 取得的設定
};
const firebaseApp = initializeApp(firebaseConfig);
const auth = getAuth(firebaseApp);

// 註冊
async signUp function () {
  const email = 'xxxx@example.com';
  const password =  'ooooxxxx';
  try {
    const userCredential = await createUserWithEmailAndPassword(auth, email, password)
    const loginUser = userCredential.user
    // do something
  } catch (e) {
    alert(e.message)
  }
}

// 登入
try {
  const email = 'xxxx@example.com';
  const password =  'ooooxxxx';
  const userCredential = await signInWithEmailAndPassword(auth, email, password)
  const loginUser = userCredential.user
} catch (e) {
  alert(e.message)
}

※ 信箱驗證與修改密碼這邊就省略了,可以去查看官方文件:https://firebase.google.com/docs/auth/web/email-link-auth

Google 登入

而如果要啟用 Google 進行登入會更方便,可以省去寫註冊、修改密碼、忘記密碼相關 UI

接著點「啟用」,其中「專案公開名稱」與「支援電子信箱」直接選就可以預設就可以了

接著在 Settings 加上授權網域

接著就能夠使用 Google 登入的功能了

import { initializeApp } from "firebase/app";
import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth";

const firebaseConfig = {
  // ... 取得的設定
};
const firebaseApp = initializeApp(firebaseConfig);
const auth = getAuth(firebaseApp);

try {
  const provider = new GoogleAuthProvider();
  provider.addScope('https://www.googleapis.com/auth/contacts.readonly');
  const result = await signInWithPopup(auth, provider)

  const credential = GoogleAuthProvider.credentialFromResult(result);
  const loginUser = result.user;
  const token = credential.accessToken;
} catch (e) {
  console.log(e);
}

Realtime Database

如果是要有個很簡易的儲存空間,不需要有複雜的 transaction 商業邏輯,可以使用 Firebase 的 Realtime Database,其是使用一個巨大的 JSON 進行資料儲存,開發者可以依照自己使用的情境來使用不同 path 存放資料,並且可以做到依據帳號儲存自己的資料

點選左方的 Realtime Database

接著點「建立資料庫」

以台灣最近的地區可以選擇新加坡

接著先以「鎖定模式」啟動

啟用後可以看到資料庫的內容,目前只有 null

接著點選規則頁面,目前預設的規則是禁止寫入與禁止讀取

可以把規則改成如下面,表示 users/$uid 下的資料只有在使用者本人登入狀態下可以寫入與讀取

{
  "rules": {
    "test": {
      ".read": true,
      ".write": true
    },
    "users": {
      "$uid": {
        ".write": "$uid === auth.uid",
        ".read": "$uid === auth.uid"
      }
    }
  }
}

此時就就可以開始使用

import { initializeApp } from "firebase/app";
import { getDatabase, ref, set } from "firebase/database";

const firebaseConfig = {
  // ... 取得的設定
};
const firebaseApp = initializeApp(firebaseConfig);

async function writeUserData() {
  const database = getDatabase(firebaseApp);
  // 寫入資料到 user 自己的路徑中
  // (不需要設定 token, 只要登入後會直接綁定狀態在 firebase 上)
  const dataRef = ref(database, 'users/' + loginUser.uid + '/example');
  await set(dataRef, {
    // ... 要儲存的資料
  });
}

async function readUserData() {
  const database = getDatabase(firebaseApp);
  // 讀取 user 自己的路徑中的資料
  // (不需要設定 token, 只要登入後會直接綁定狀態在 firebase 上)
  const dataRef = ref(database, 'users/' + loginUser.uid + '/example');
  const snapshot = await get(dataRef);
  const data = snapshot.val();
}

發表迴響