使用Firebase構建雲端應用:建立項目和用戶管理

在構建本身的在線雲工具應用時,我使用 Firebase 爲本身的「無後端項目」提供服務,把在開發期間接觸到的一些內容整理在一塊兒,製成系列筆記。這個過程有兩個好處:鞏固知識點,整理開發過程的思路。由於前端開發是本身所熟悉的領域,因此先從 Firebase 入手,將後端的一些知識點提早梳理理順,避免後續的學習過程當中的卡殼而致使沒法堅持。今天第一期:建立項目和用戶管理。前端

什麼是 Firebase

Firebase 本來是一家實時後端數據庫創業公司,爲提供一個實時響應的數據服務。後被 Google 收購,該平臺適用在IOS、Android、web前端等各類跨平臺上,對於沒有數據庫處理經驗的開發者,只需使用本身熟悉的語言將數據放在Firebase上,再經過Firebase提供的API便可實現實時數據同步。同時 Google 在新版的 Firebase 中包含開發、成長與營收三階段,並整合分析工具,不過度析工具目前只針對移動 App,網頁的話能夠繼續使用 Google Analytics。git

何謂「實時數據庫」?簡單粗暴的理解就是,數據庫中數據的變更會互動通知到客戶端。同一帳號在客戶端 A出操做,客戶端 B 會收到相應的通知。根據我在瀏覽器中的調試,發如今 Web 端 原來是用的 WebSocket。考慮到寫數據時遇到的無網絡鏈接問題,Firebase的數據庫API使用了本地緩存,使得在離線狀態下也能保持讀寫不失敗,而且會在網絡恢復鏈接時和服務器進行同步。github

Firebase 提供了四種 SDK: Android,IOS, Web 和 C++。我將使用 Web 端 SDK 開發一個無後端的筆記應用。web

關聯應用

在使用 Firebase 做爲後端數據庫以前,須要登陸 Firebase 的控制檯,添加一個 Firebase 的網絡應用。你可選擇新建一個應用,或者導入一個現有的 Google 項目。數據庫

建立完應用以後,進入應用的控制面板,在 ‘https://console.firebase.goog...’ 中能夠看到碩大的綁定入口「將 Firebase 添加到您的網頁應用」,點擊以後,將給處的 JavaScript 添加到 HTML 文件中。npm

<script src="https://www.gstatic.com/firebasejs/3.4.0/firebase.js"></script>
  <script>
    // Initialize Firebase
    let config = {
      apiKey: '<your-api-key>',
      authDomain: '<your-auth-domain>',
      databaseURL: '<your-database-url>',
      storageBucket: '<your-storage-bucket>'
    };
    firebase.initializeApp(config);
  </script>

固然也可經過 npm 安裝 Firebase 的 SDK npm link,而後經過 Webpack 等工具打包。後端

npm install --save firebase

引入 Firebaseapi

let firebase = require('firebase');
let app = firebase.initializeApp({ ... });

完整的 Firebase 客戶端包包含了Firebase 的 Authentication, Realtime Database, Storage 和 Cloud Messaging。上面的代碼將會把這些功能所有引入。能夠將這些功能以獨立組件的形式引入,減小代碼量。瀏覽器

  • firebase-app 核心代碼(必需)緩存

  • firebase-auth Authentication(可選)

  • firebase-database Realtime Database(可選)

  • firebase-storage Storage(可選)

  • firebase-messaging Cloud Messagin(可選)

在這個案例中目前 Storage暫時沒有使用的計劃,Cloud Messaging 針對的是移動端,因此這兩個組件不引入。

let firebase = require('firebase/app');
require('firebase/auth');
require('firebase/database');
 
let app = firebase.initializeApp({ ... });
// ...

完成上述步驟以後,你已經能夠在環境中使用 firebase 提供的各類接口了。

用戶

大多數應用都須要瞭解用戶的身份。知道用戶的身份可讓應用將用戶數據安全地保存在雲中並跨全部用戶設備提供相同的個性化體驗。
Firebase Authentication 提供後端服務、易用 SDK 和現成 UI 庫來嚮應用驗證用戶的身份。它支持使用密碼、深受歡迎的聯合用戶身份提供商(如 Google、Facebook 和 Twitter)等方法進行身份驗證。

本次案例使用第三方登陸,不使用 Firebase 提供的 UI庫,有興趣的朋友能夠本身去試試 https://github.com/firebase/FirebaseUI-Web

在添加了 Firebase應用以後,打開console的 Authentication,在登陸方法中開啓須要的登陸提供商。這裏我選擇了「電子郵件地址/密碼」和「Github「兩種方式。

建立基於密碼的賬戶

在用戶填寫表單註冊時,完成所需的任何新賬戶驗證步驟,例如驗證新賬號密碼鍵入正確,或者檢查帳號是否已經存在。而後
將郵件地址和密碼傳遞到 createUserWithEmailAndPassword 方法中來建立新賬戶:

firebase.auth().signInWithEmailAndPassword(email, password).catch((error) => {
  // Handle Errors here.
  let errorCode = error.code;
  let errorMessage = error.message;
  // ...
});

用戶首次登陸後,便會創建一個新用戶賬戶並連接至該用戶登陸時使用的憑據,即用戶名和密碼,或身份驗證提供程序信息。此新賬戶存儲在 Firebase 項目中,可用於跨項目中的每一個應用識別用戶,不管該用戶如何登陸。

使用 Github 帳號登陸

在console 中的登陸方式中啓用 github 登陸以後,須要添加從 GitHub 得到的 OAuth 2.0 客戶端 ID 和客戶端密鑰。同時將你的 Github 應用的受權回調地址設置爲 Firebase OAuth 重定向 URI(例如 my-app-12345.firebaseapp.com/__/auth/handler)。Github 的應用配置

上述前期工做準備就緒以後,能夠開始使用 Firebase SDK 來使用登陸流程。

先建立一個 GitHub 提供程序對象的實例:

let provider = new firebase.auth.GithubAuthProvider();

而後是一個可選的步驟:從身份驗證提供程序中指定您想請求的其餘 OAuth 2.0 範圍。調用 Provider 實例的 addScope方法來添加範圍。例如:

provider.addScope('repo');

詳細參數能夠參考身份驗證提供程序文檔

接下來,使用 GitHub 提供程序對象進行 Firebase 身份驗證。能夠提示用戶,讓其經過打開彈出式窗口或重定向登陸頁面的方法以本身的 GitHub account 登陸。移動設備最好使用重定向方法。要用彈出式窗口的方法登陸,調用 signInWithPopup:

firebase.auth().signInWithPopup(provider).then(function(result) {
  // This gives you a GitHub Access Token. You can use it to access the GitHub API.
  let token = result.credential.accessToken;
  // The signed-in user info.
  let user = result.user;
  // ...
}).catch(function(error) {
  // Handle Errors here.
  let errorCode = error.code;
  let errorMessage = error.message;
  // The email of the user's account used.
  let email = error.email;
  // The firebase.auth.AuthCredential type that was used.
  let credential = error.credential;
  // ...
});

你能夠檢索 GitHub 提供程序的 OAuth 令牌,使用該令牌可經過 GitHub API 提取額外數據。
還能夠經過這種方法捕獲並處理錯誤。獲取錯誤代碼列表

若是要用重定向登陸頁面的方法登陸,則調用 signInWithRedirect:

firebase.auth().signInWithRedirect(provider);

不只如此,你還能夠在頁面加載時經過調用 getRedirectResult 檢索 GitHub 提供程序的 OAuth 令牌:

firebase.auth().getRedirectResult().then(function(result) {
  if (result.credential) {
    // This gives you a GitHub Access Token. You can use it to access the GitHub API.
    let token = result.credential.accessToken;
    // ...
  }
  // The signed-in user info.
  let user = result.user;
}).catch(function(error) {
  // Handle Errors here.
  let errorCode = error.code;
  let errorMessage = error.message;
  // The email of the user's account used.
  let email = error.email;
  // The firebase.auth.AuthCredential type that was used.
  let credential = error.credential;
  // ...
});

固然,你也能夠手動處理登陸流程。 在 GitHub 登陸流程結束後,你會收到一個 OAuth 2.0 訪問令牌。在用戶使用 GitHub 成功登陸以後,先使用 OAuth 2.0 訪問令牌換取 Firebase 憑據:

let credential = firebase.auth.GithubAuthProvider.credential(token);

而後使用 Firebase 憑據進行 Firebase 身份驗證:

firebase.auth().signInWithCredential(credential).catch(function(error) {
  // Handle Errors here.
  let errorCode = error.code;
  let errorMessage = error.message;
  // The email of the user's account used.
  let email = error.email;
  // The firebase.auth.AuthCredential type that was used.
  let credential = error.credential;
  // ...
});

除了前面提到的郵箱密碼驗證,第三方 OAuth 驗證以外,Firebase 還支持自定義身份認證系統和匿名身份驗證,這裏不講,有興趣和需求的朋友能夠本身去了解。

其餘用戶管理操做的支持

要註銷用戶,調用 signOut:

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}, function(error) {
  // An error happened.
});

除此以外,SDK 還提供了一系列用戶管理的方法。

  • 獲取當前登陸的用戶

獲取當前用戶的推薦方法是在 Auth 對象上調用onAuthStateChanged方法,這可確保在您獲取當前用戶時,Auth 對象不會處於中間狀態,例如初始化。既要麼未登陸,要麼已登陸。

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    // User is signed in.
  } else {
    // No user is signed in.
  }
});

也可使用 currentUser 屬性獲取當前已登陸的用戶。 若是用戶沒有登陸,currentUser 則爲 null:

let user = firebase.auth().currentUser;

if (user) {
  // User is signed in.
} else {
  // No user is signed in.
}

不過有一點要注意,currentUser 還可能因爲 auth 對象還沒有完成初始化而爲 null。 若是使用觀察程序跟蹤用戶登陸狀態,則無需處理該狀況。
當獲取到用戶對象的實例以後,能夠訪問實例上的一些屬性,以及調用實例上的一些方法對用戶進行一些操做,好比:

  • 要獲取用戶的我的資料信息:

let user = firebase.auth().currentUser;
let name, email, photoUrl, uid;

if (user != null) {
  name = user.displayName;
  email = user.email;
  photoUrl = user.photoURL;
  uid = user.uid;  // The user's ID, unique to the Firebase project. Do NOT use
                   // this value to authenticate with your backend server, if
                   // you have one. Use User.getToken() instead.
}
  • 獲取用戶的特定於提供程序的我的資料信息(登陸提供程序中獲取檢索到的我的資料信息)

let user = firebase.auth().currentUser;

if (user != null) {
  user.providerData.forEach(function (profile) {
    console.log("Sign-in provider: "+profile.providerId);
    console.log("  Provider-specific UID: "+profile.uid);
    console.log("  Name: "+profile.displayName);
    console.log("  Email: "+profile.email);
    console.log("  Photo URL: "+profile.photoURL);
  });
}
  • 更新用戶我的資料(顯示名稱和頭像地址)

let user = firebase.auth().currentUser;

user.updateProfile({
  displayName: "Jane Q. User",
  photoURL: "https://example.com/jane-q-user/profile.jpg"
}).then(function() {
  // Update successful.
}, function(error) {
  // An error happened.
});
  • 設置電子郵件地址

let user = firebase.auth().currentUser;

user.updateEmail("user@example.com").then(function() {
  // Update successful.
}, function(error) {
  // An error happened.
});

要設置用戶的電子郵件地址,該用戶必須最近登陸過。在 Firebase 控制檯的"Authentication"的"Email Templates"頁面中容許自定義使用的電子郵件模板。

  • 設置用戶密碼

let user = firebase.auth().currentUser;
let newPassword = getASecureRandomPassword();

user.updatePassword(newPassword).then(function() {
  // Update successful.
}, function(error) {
  // An error happened.
});
  • 刪除用戶

也能夠在控制檯中手動刪除用戶

let user = firebase.auth().currentUser;

user.delete().then(function() {
  // User deleted.
}, function(error) {
  // An error happened.
});

有些安全敏感性操做,好比刪除賬戶、設置主電子郵件地址和更改密碼,須要用戶最近登陸過才能執行。若是要執行這些操做中的某一項,而用戶只是在好久之前登陸過,操做便出錯。發生這種錯誤時,須要從用戶獲取新登陸憑據,將該憑據傳給 reauthenticate ,對該用戶從新進行身份驗證。

let user = firebase.auth().currentUser;
let credential;

// Prompt the user to re-provide their sign-in credentials

user.reauthenticate(credential).then(function() {
  // User re-authenticated.
}, function(error) {
  // An error happened.
});

結束

如此一來,個人應用已經能夠支持郵箱密碼登陸,github 帳號登陸。並且用戶的管理操做也有很直接明瞭的方法。當用戶添加以後,接下來就能夠圍繞用戶設計出須要的數據結構了。下回:數據結構的定義及數據的操做,敬請期待

相關文章
相關標籤/搜索