iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 10
1
Mobile Development

Flutter---Google推出的跨平台框架,Android、iOS一起搞定系列 第 10

【Flutter基礎概念與實作】 Day10–Firebase與Bloc Design Pattern

今天會介紹如何設定Firebase auth並且新增「UserRepository」用來和Firebase溝通,以便驗證和取得使用者資訊。 最後會提到一些Bloc的概念。

首先要來介紹的Firebase是Google旗下的服務,讓開發人員能夠快速建置App,提供如數據分析、資料庫、帳號權限驗證機制、訊息推播等方便功能

若只是要開發小型App或Demo App,使用Firebase讓你可以少花時間去設置資料庫或處理登入註冊的流程,能更專注在實際應用的開發。

這次我們要使用的是Firebase提供的Authentication服務,包含帳號註冊與權限控管,支援各大社群如Google、Facebook、Github等等平台。

接下來介紹如何設置Firebase:

  1. 進入到Firebase首頁

  2. 點選Get Started並登入你的Google帳號

  3. 進入主控台,選擇建立專案

  4. 幫專案取個名稱(不需和Flutter專案同名),其他就勾選同意和繼續
    https://ithelp.ithome.com.tw/upload/images/20190920/201195501s9nxvIHd8.png

  5. 點選Android Icon新增Android應用程式(如果要新增iOS請看這邊的教學)

  6. Android套件名稱可從Flutter專案/android/app/src/main/AndroidManiest.xml找到

  7. 憑證SHA-1取得步驟:
    a. 使用cmd或PowerShell到C:\Program Files\Java\jdk1.8.0_181\bin路徑
    b. 輸入keytool -exportcert -list -v -alias androiddebugkey -keystore C:/Users/[你的windows使用者帳號]/.android/debug.keystore
    c. 輸入預設密碼android

    d. 複製SHA1憑證貼到Firebase註冊欄內

  8. 上述資訊填入後系統會產生google-services.json讓你下載

  9. 依照圖示將json檔放到Flutter專案/android/app路徑下

  10. 新增引用Firebase SDK,同樣照著圖示修改即可


以上設定完成後,便到Authentication功能將電子郵件以及Google登入都啟用。


這樣Firebase Auth的部分我們都設定好啦,接下來回到App的部分。


本專案驗證及註冊程式碼參考至Felix Angelov的Bloc Tutorial

開啟pubspec.yaml下載以下Packages

cloud_firestore: ^0.12.9+3
firebase_auth: ^0.14.0+5
google_sign_in: ^4.0.7
flutter_bloc: ^0.21.0 
equatable: ^0.5.1
meta: ^1.1.6
font_awesome_flutter: ^8.5.0
flutter_auth_buttons: ^0.5.0

新增UserRepository

新建firebase資料夾放和firebase有關的操作檔案,並新增user_repository.dart。

fluttube
└───lib
│   └───firebase
│   │   └───user_repository.dart
│   └───login
│   │   └───login_page.dart
│   └───main.dart
│   └───splash_page.dart  
│

user_repository程式碼:

import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';

class UserRepository {
  final FirebaseAuth _firebaseAuth;
  final GoogleSignIn _googleSignIn;

  UserRepository({FirebaseAuth firebaseAuth, GoogleSignIn googleSignin})
      : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance,
        _googleSignIn = googleSignin ?? GoogleSignIn();

  Future<FirebaseUser> signInWithGoogle() async {

    final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
    final GoogleSignInAuthentication googleAuth =
        await googleUser.authentication;

    final AuthCredential credential = GoogleAuthProvider.getCredential(
      accessToken: googleAuth.accessToken,
      idToken: googleAuth.idToken,
    );
    await _firebaseAuth.signInWithCredential(credential);
    return _firebaseAuth.currentUser();
  }

  Future<void> signInWithCredentials(String email, String password) {
    return _firebaseAuth.signInWithEmailAndPassword(
      email: email,
      password: password,
    );
  }

  Future<void> signUp({String email, String password}) async {
    return await _firebaseAuth.createUserWithEmailAndPassword(
      email: email,
      password: password,
    );
  }

  Future<void> signOut() async {
    return Future.wait([
      _firebaseAuth.signOut(),
      _googleSignIn.signOut(),
    ]);
  }

  Future<bool> isSignedIn() async {
    final currentUser = await _firebaseAuth.currentUser();
    return currentUser != null;
  }

  Future<String> getUser() async {
    return (await _firebaseAuth.currentUser()).email;
  }
}

我們建立UserRepository Class用來呼叫Firebase驗證,並在建構子檢查是否有給予Firebase和GoogleSignIn的實體,如果沒有給予,則初始化它們。

 UserRepository({FirebaseAuth firebaseAuth, GoogleSignIn googleSignin})
      : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance,
        _googleSignIn = googleSignin ?? GoogleSignIn();

// ?? operator:如果左邊不是null,就回傳左邊,左邊若是null就回傳右邊 

signInWithGoogle會進行Google驗證,會跳出常見的Google登入畫面。
signInWithCredentials會將使用者輸入的信箱及密碼傳到Firebase Server去做驗證。
可以注意的是這裡Function的回傳值都是Future物件,這是因為操作都牽涉到網路傳輸,所以會使用非同步進行。


今天App實作部分先到此告一段落,由於我們的驗證和登入機制要使用BLoC Pattern來實作,因此接下來要先來介紹Bloc Design Pattern。

什麼是BLoC Design Pattern


BLOC全名是「Business Logic Component」,用來分離UI層和商業邏輯層,有助於程式碼的維護、重複利用以及測試。
上面是我畫的示意圖,可能不完全正確但大致能表達意思,BLOC層會接收使用者的行為(例如點擊Button),根據不同的事件(Event)Bloc會去呼叫相應的函式(可能是去資料庫抓資料或使用api)。之後根據結果回傳相應的狀態(State)給UI層,UI則根據狀態做變化。

Bloc只是一個概念,每個人實作的方式都不同,這次的實作我採用的是Felix Angelov開發的「Flutter Bloc」套件,因為它使用起來相對簡單易懂(而且有許多Example可以參考)。

Stream

Stream是實作Bloc的基礎概念,可以把Stream想成資料流或是一個水管,輸入某些Input(sink),經過水管內的處理(Business Logic),它會吐出處理好的Output(Stream)。

使用Stream,UI層就透過可以觸發事件(Sink data),及監聽Output的Stream達到分離商業邏輯的效果。

更詳細的Stream介紹可以看這篇
也可以參考同個作者的BLoC實作,他使用Bloc取代原本用setState更新的計步器App。

今日總結

今天介紹如何設定Firebase專案以及開啟Authentication功能,且新增了UserRepository協助我們和Firebase服務溝通。
並介紹BLoC Design Pattern的概念,如果想瞭解它誕生的原因及更深入的介紹可以觀看這兩部影片。
Flutter / AngularDart – Code sharing, better together (DartConf 2018)
Build reactive mobile apps with Flutter (Google I/O '18)
明天會針對Flutter Bloc框架來作介紹,包含它的架構和元件的使用方法。


上一篇
【Flutter基礎概念與實作】 Day9–建立專案與App開頭動畫
下一篇
【Flutter基礎概念與實作】 Day11–Flutter Bloc 套件介紹 (1) Events、States和Transitions
系列文
Flutter---Google推出的跨平台框架,Android、iOS一起搞定30

尚未有邦友留言

立即登入留言