2018年10月11日 星期四

【Ionic 4】會員Email註冊-以Firebase為雲端平台(含FormBuilder表單與輸入驗證)

Firebase支援「Email/密碼登入與註冊」以及多種OAuth登入方式,如Google,Twitter,Facebook等,本文說明如何使用Firebase「Email/密碼」認證API,設計會員Email註冊功能。除此之外,註冊表單則以Reactive Forms(FormBuilder)設計,並帶有輸入驗證功能,如下圖所示。
有驗證功能的註冊表單。註冊與登出都是使用Firebase認證API
此App有註冊、HomePage兩個頁面。首頁設定為註冊頁面,註冊後,會在Cloud Firestore新增會員資料,並轉往HomePage;在HomePage按下登出又會回註冊頁面。完整程式碼在Github。製作重要步驟如下:

Step 1:建立專案
除了前述註冊與HomePage兩個頁面,須另建立登入服務AuthService,處理Firebase Email/密碼註冊功能,以及登出:
ionic start RegisterExample blank --type=angular
cd RegisterExample
ionic g page register
ionic g service services/auth
而為了使用Firebase認證API,必須安裝firebase與@angular/fire兩個套件:
npm install firebase @angular/fire
Step 1.1:加入Firebase連線設定
Firebase控制台建立專案後,進入專案資料庫,建立Cloud Firestore資料庫:
Cloud Firestore是Firebase新版的NoSQL文件資料庫
接著先「以測試模式啟動」,方便後續測試。不過需注意畫面提醒訊息:測試模式,所有使用者都有存取權限。後續務必要自行設定安全性規則。
以測試模式啟動Cloud Firestore,方便測試
緊接著,在[Project Overview] 下,新增應用程式,點取「網路應用程式」符號(如下圖),以便取得Ionic App連線時所需參數設定值:
選取網路應用程式
Ionic App所需連線參數
如上圖,複製反白區域的程式碼。
修改src/environments/environment.ts檔,將上述程式碼貼入其中,如下:
最後,修改app.module.ts,引入AngularFireModule模組與environment元件,同時設定AngularFireModule.initializeApp(),帶入Firebase連線所需參數:
Step 1.2:修改app-routing.module.ts
為了展示方便,將首頁改至"register",直接進入RegisterPage,如下之第3行:
Step 2: 編修註冊頁面
Step 2.1: 修改register.module.ts,引入ReactiveFormsModule
但由於Ionic 4 CLI建立頁面時,會產生lazy loading頁面,每個頁面有自己的模組檔;因此,import ReactiveFormsModule是加在RegisterPage的模組檔-register.module.ts檔:
import { ReactiveFormsModule } from '@angular/forms';
而不是加在最上層的app.module.ts。
Step 2.2:製作註冊表單
以FormGroup製作表單,使用Validators內建功能驗證欄位輸入,重點摘要如下:

  • 第2行:引入FormBuilder等元件。
  • 第18行:FormBuilder提供group()功能,可設定表單欄位。
  • 第19-21行:每一欄位有其名稱,如19行之email;另外可訂定驗證規則。20行使用了必要欄位與email格式驗證(Validators.email)。22~24行則是訂定displayName欄位與其驗證規則。
  • 第25-35行:密碼欄位比較特殊,除了第28行.pattern(),用regular expression定義密碼格式外,還有password, confirmPassword兩個欄位的比對需求。因此,第23行改用new FormGroup製作子群組,將password, confirmPassword歸入同群組,並在第35行設定此群組的驗證規則MatchPassword(位於src/app/_validators/password.validator.ts)。
  • 第39行:訂閱valueChanges服務,監聽表單內容變動。一旦有所變動,則交由自訂函數onValueChange()進行判讀,並顯示錯誤訊息。
如上所述,需另外撰寫密碼比對是否相符的驗證函式MatchPassword,以及自訂內容變動判讀函式onValueChange()。
Step 2.3 加入密碼比對函式
密碼比對需使用@angular/forms的AbstractControl。透過AbstractControl定義的屬性,如value,可讓validator取得輸入欄位的值。新增src/app/_validators/password.validator.ts,並加入下列程式碼:
唯一要注意是:自訂validator當「比對失敗」時,要回傳true(如第8行),否則回傳null(第10行)。
Step 2.4 加入內容變動判讀onValueChange()
此處將所有輸入驗證的錯誤訊息定義於validatorMessages物件,另外formErrors則是列出各欄位與額外加上的validator,onValueChange()每次執行,都會依序檢視formErrors每一項目,看是否有錯誤訊息。部份程式碼如下:

  • 第35-40行:一般預設的驗證都是如35行以dirty, not valid皆成立,確認輸入驗證失敗,此時便要顯示錯誤訊息。
  • 第42-48行:密碼比對較為複雜,需透過上層的passwordGroup,才能取得其內的兩組密碼欄位,錯誤判斷規則如44-45所示。
Step 3 註冊連帶建立會員資料
services/auth.service.ts提供Firebase註冊服務,並在註冊時,一併建立會員資料。程式碼如下:

  • 第21行:訂閱authState,如此一旦有登入或登出時,便會取得第22行user值(登入時為user資料,登出時為null)。因此如有登入,this.user便會填入current user(如24行)。
  • 第32-38行:createUserWithEmailAndPassword()是Firebase註冊功能,會在Firebase後台建立一組email帳號(需6位以上)。但為了在Firestore資料庫產生相對應會員資料,35行呼叫自訂函式updateUserData()。
  • 第40-44行:登出。透過Router轉向首頁。
  • 第46-53行:userRef指向Cloud Firestore資料庫users集合內之文件;該文件的文件id:${user.uid}是在33行註冊時,系統產生的「使用者UID」,且已記錄於Firebase Authentication表格裡。如此使用者登入時,藉由UID便可取得users集合內對應到此user的文件。48-51設定表單傳送過來的user資料,52行將資料寫入Cloud Firestore。

最後,為了方便寫入user資料,另外定義了_model/user.ts,裡面定義了users集合內,各文件應該有的欄位。專案完整程式碼在Github,惟在git clone後,需改寫environment.ts裡關於Firebase的連線設定。

使用版本
firebase 5.5.3
@angular/fire 5.0.2


沒有留言:

張貼留言