透過 FirebaseUI 輕鬆將登入程序新增至 iOS 應用程式

FirebaseUI 是建構在 Firebase Authentication SDK 之上的程式庫,可提供用於應用程式的內建 UI 流程。FirebaseUI 具有下列優點:

  • 多個供應商:電子郵件/密碼、電子郵件連結、電話驗證、Google 登入、Facebook 登入和 Twitter 登入的登入流程。
  • 帳戶管理:處理帳戶管理工作的流程,例如帳戶建立和密碼重設。
  • 匿名帳戶連結:自動將匿名帳戶連結至識別資訊提供者。
  • 可自訂:配合應用程式自訂 FirebaseUI 的外觀。此外,由於 FirebaseUI 是開放原始碼,因此您可以將專案分支,並根據自己的需求自訂。

事前準備

  1. 將 Firebase 新增至 Apple 專案

  2. 將 FirebaseUI 新增至 Podfile:

    pod 'FirebaseUI'
    

    如有需要,您可以只新增驗證元件和要使用的供應商:

    pod 'FirebaseUI/Auth'
    
    pod 'FirebaseUI/Google'
    pod 'FirebaseUI/Facebook'
    pod 'FirebaseUI/OAuth' # Used for Sign in with Apple, Twitter, etc
    pod 'FirebaseUI/Phone'
    
  3. 如果您尚未將應用程式連結至 Firebase 專案,請透過 Firebase 主控台進行。

設定登入方式

您必須先啟用並設定您想支援的登入方式,才能使用 Firebase 登入使用者。

電子郵件地址和密碼

Firebase 控制台開啟「Authentication」部分,啟用電子郵件和密碼驗證。

  1. Firebase 控制台開啟「驗證」專區。在「Sign in method」分頁中,啟用「Email/Password」供應商。請注意,您必須啟用電子郵件或密碼登入功能,才能使用電子郵件連結登入功能。

  2. 在相同區段中,啟用「Email link (無密碼登入)」登入方式,然後按一下「Save」(儲存)

  3. 您可以透過使用 FIREmailLinkAuthSignInMethod 初始化 FUIEmailAuth 例項,啟用電子郵件連結登入功能。您還需要提供有效的 FIRActionCodeSettings 物件,並將 handleCodeInApp 設為 true。

Swift

var actionCodeSettings = ActionCodeSettings()
actionCodeSettings.url = URL(string: "https://example.appspot.com")
actionCodeSettings.handleCodeInApp = true
actionCodeSettings.setAndroidPackageName("com.firebase.example", installIfNotAvailable: false, minimumVersion: "12")

let provider = FUIEmailAuth(authUI: FUIAuth.defaultAuthUI()!,
                            signInMethod: FIREmailLinkAuthSignInMethod,
                            forceSameDevice: false,
                            allowNewEmailAccounts: true,
                            actionCodeSetting: actionCodeSettings)

Objective-C

FIRActionCodeSettings *actionCodeSettings = [[FIRActionCodeSettings alloc] init];
actionCodeSettings.URL = [NSURL URLWithString:@"https://example.appspot.com"];
actionCodeSettings.handleCodeInApp = YES;
[actionCodeSettings setAndroidPackageName:@"com.firebase.example"
                    installIfNotAvailable:NO
                           minimumVersion:@"12"];

id<FUIAuthProvider> provider = [[FUIEmailAuth alloc] initWithAuthUI:[FUIAuth defaultAuthUI]
                                                       signInMethod:FIREmailLinkAuthSignInMethod
                                                    forceSameDevice:NO
                                              allowNewEmailAccounts:YES
                                                  actionCodeSetting:actionCodeSettings];
  1. 此外,您必須將傳遞至 iniatializer 的網址加入許可清單。您可以在 Firebase 控制台開啟「Authentication」專區。在「Sign in method」分頁的「Authorized domains」底下新增網址。

  2. 擷取深層連結後,您需將其傳遞至驗證 UI,以便系統進行處理。

Swift

FUIAuth.defaultAuthUI()!.handleOpen(url, sourceApplication: sourceApplication)

Objective-C

[[FUIAuth defaultAuthUI] handleOpenURL:url sourceApplication:sourceApplication];
  1. FirebaseUI-iOS 的電子郵件連結登入功能與 FirebaseUI-AndroidFirebaseUI-web 相容,讓從 FirebaseUI-Android 啟動流程的一位使用者可以開啟連結,並使用 FirebaseUI-web 完成登入。反向流程也是如此。

Apple

  1. 參閱 Firebase「使用 Apple 帳戶登入」指南中的「事前準備」和「遵守 Apple 匿名資料規定」章節。

  2. 在授權檔案中加入「使用 Apple 帳戶登入」功能。

  3. 初始化為「使用 Apple 登入」設定的 OAuth 提供者執行個體:

    Swift

    provider = FUIOAuth.appleAuthProvider()
    

    Objective-C

    FUIOAuth *provider = [FUIOAuth appleAuthProvider];
    

Google

  1. 使用此教學課程設定 Google 登入功能

Facebook

  1. 按照 Facebook 入門指南設定 Facebook Login SDK。

  2. Firebase 主控台中開啟「Authentication」區段並啟用 Facebook。如要啟用 Facebook 登入功能,您必須提供 Facebook 應用程式 ID 和應用程式密鑰 (可在 Facebook Developers Console 中取得)。

  3. 依序前往「Project Settings」>「Capabilities」畫面,在 Xcode 專案中啟用鑰匙圈共用。

  4. fbFACEBOOK_APP_ID 新增為 Xcode 專案中的網址配置。

  5. Info.plist 檔案中新增 Facebook 應用程式 ID 和顯示名稱:

    價值
    Facebook 應用程式 ID FACEBOOK_APP_ID (例如:1234567890)
    Facebook 顯示名稱 應用程式名稱
  6. 初始化 Facebook 提供者執行個體:

    Swift

    provider = FUIFacebookAuth(authUI: FUIAuth.defaultAuthUI())
    

    Objective-C

    FUIFacebookAuth *provider = [[FUIFacebookAuth alloc] initWithAuthUI:[FUIAuth defaultAuthUI]];
    

  7. 如要使用 Facebook 有限登入,請在 FUIFacebookAuth 執行個體上設定 useLimitedLogin 屬性。

    Swift

    provider.useLimitedLogin = true
    

    Objective-C

    provider.useLimitedLogin = YES;
    

Twitter

  1. Firebase 控制台中開啟「Authentication」區段並啟用 Twitter。如要啟用 Twitter 登入功能,您必須提供 Twitter API 用戶端金鑰和密鑰,可在 Twitter 應用程式管理主控台中找到。

  2. 初始化為 Twitter 登入設定的 OAuth 提供者執行個體:

    Swift

    provider = FUIOAuth.twitterAuthProvider()
    

    Objective-C

    FUIOAuth *provider = [FUIOAuth twitterAuthProvider];
    

電話號碼

  1. Firebase 控制台中開啟「Authentication」區段,並啟用電話號碼登入功能。

  2. Firebase 必須能夠驗證應用程式發出的電話號碼登入要求是來自應用程式,其中一種方法是透過 APN 通知。詳情請參閱「啟用應用程式驗證功能」一文。

    如何啟用與 Firebase 驗證搭配使用的 APN 通知:

    1. 在 Xcode 中,為專案啟用推播通知

    2. 將 APN 驗證金鑰上傳至 Firebase。如果您還沒有 APN 驗證金鑰,請務必前往 Apple Developer Member Center 建立 APN 驗證金鑰。

      1. 在 Firebase 控制台的專案中,依序選取齒輪圖示 >「專案設定」,然後選取「雲端通訊」分頁標籤。

      2. 在「iOS app configuration」下方的「APNs 驗證金鑰」中,按一下「上傳」按鈕。

      3. 瀏覽至您儲存金鑰的位置,選取金鑰,然後按一下 [Open] (開啟)。加入金鑰金鑰 ID (可於 Apple Developer Member Center 中找到),然後按一下「上傳」

      如果您已有 APN 憑證,可以改為上傳憑證。

  3. 如果裝置上無法接收 APN 通知,Firebase 會使用 reCAPTCHA 驗證要求。

    如要啟用 reCAPTCHA 驗證,請在 Xcode 中執行下列步驟:

    1. 開啟專案設定:在左側樹狀檢視中,按兩下專案名稱。從「TARGETS」(目標) 部分選取您的應用程式,選取「Info」(資訊) 分頁標籤,然後展開「URL Types」(網址類型) 部分。
    2. 按一下「+」按鈕,然後新增您的編碼應用程式 ID 做為網址配置。前往 Firebase 控制台的「一般設定」頁面,即可在 iOS 應用程式專區中找到經過編碼的應用程式 ID。請將其他欄位留白。

      設定完成後,設定看起來應類似下列內容 (但會使用您的應用程式專屬值):

      Xcode 自訂網址配置設定介面的螢幕擷取畫面
  4. 選用:Firebase 會使用方法滑動自動取得應用程式的 APN 權杖,處理 Firebase 傳送至應用程式的無訊息推播通知,並在驗證期間自動攔截來自 reCAPTCHA 驗證頁面的自訂配置重新導向。

    如果不想使用浮動式登入功能,請參閱 Firebase SDK 驗證文件中的「附錄:以不透過疑惑的方式使用手機登入」一文。

登入

如要啟動 FirebaseUI 登入流程,請先初始化 FirebaseUI:

Swift

import FirebaseAuthUI

/* ... */

FirebaseApp.configure()
let authUI = FUIAuth.defaultAuthUI()
// You need to adopt a FUIAuthDelegate protocol to receive callback
authUI.delegate = self

Objective-C

@import FirebaseAuthUI;

...

[FIRApp configure];
FUIAuth *authUI = [FUIAuth defaultAuthUI];
// You need to adopt a FUIAuthDelegate protocol to receive callback
authUI.delegate = self;

接著,將 FirebaseUI 設為使用您要支援的登入方式:

Swift

import FirebaseAuthUI
import FirebaseFacebookAuthUI
import FirebaseGoogleAuthUI
import FirebaseOAuthUI
import FirebasePhoneAuthUI

let providers: [FUIAuthProvider] = [
  FUIGoogleAuth(),
  FUIFacebookAuth(),
  FUITwitterAuth(),
  FUIPhoneAuth(authUI:FUIAuth.defaultAuthUI()),
]
self.authUI.providers = providers

Objective-C

@import FirebaseAuthUI;
@import FirebaseFacebookAuthUI;
@import FirebaseGoogleAuthUI;
@import FirebaseOAuthUI;
@import FirebasePhoneAuthUI;

...

NSArray<id<FUIAuthProvider>> *providers = @[
  [[FUIGoogleAuth alloc] init],
  [[FUIFacebookAuth alloc] init],
  [[FUITwitterAuth alloc] init],
  [[FUIPhoneAuth alloc] initWithAuthUI:[FUIAuth defaultAuthUI]]
];
_authUI.providers = providers;

如果您已啟用 Google 或 Facebook 登入功能,請為 Google 和 Facebook 註冊流程的結果實作處理常式:

Swift

func application(_ app: UIApplication, open url: URL,
    options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
  let sourceApplication = options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String?
  if FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication) ?? false {
    return true
  }
  // other URL handling goes here.
  return false
}

Objective-C

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary *)options {
  NSString *sourceApplication = options[UIApplicationOpenURLOptionsSourceApplicationKey];
  return [[FUIAuth defaultAuthUI] handleOpenURL:url sourceApplication:sourceApplication];
}

最後,從 FUIAuth 取得 AuthViewController 的例項。然後您可以將它顯示為應用程式的第一個檢視控制器,或讓應用程式從其他檢視控制器呈現。

Swift

如何取得登入方式選取器:

let authViewController = authUI.authViewController()

如果您只使用電話號碼登入,可以改為直接顯示電話號碼登入畫面:

let phoneProvider = FUIAuth.defaultAuthUI().providers.first as! FUIPhoneAuth
phoneProvider.signIn(withPresenting: currentlyVisibleController, phoneNumber: nil)

Objective-C

如何取得登入方式選取器:

UINavigationController *authViewController = [authUI authViewController];

如果您只使用電話號碼登入,可以改為直接顯示電話號碼登入畫面:

FUIPhoneAuth *phoneProvider = [FUIAuth defaultAuthUI].providers.firstObject;
[phoneProvider signInWithPresentingViewController:currentlyVisibleController phoneNumber:nil];

顯示驗證檢視畫面且使用者登入後,結果會透過 didSignInWithUser:error: 方法傳回 FirebaseUI 驗證委派:

Swift

func authUI(_ authUI: FUIAuth, didSignInWith user: FIRUser?, error: Error?) {
  // handle user and error as necessary
}

Objective-C

   - (void)authUI:(FUIAuth *)authUI
didSignInWithUser:(nullable FIRUser *)user
            error:(nullable NSError *)error {
  // Implement this method to handle signed in user or error if any.
}

登出

FirebaseUI 提供登出 Firebase 驗證和所有社交識別資訊提供者的便利方法:

Swift

authUI.signOut()

Objective-C

[authUI signOut];

自訂

您可以將 FirebaseUI 的檢視控制器建立子類別,並在 FUIAuth 的委派方法中指定登入畫面,藉此自訂登入畫面:

Swift

func authPickerViewController(forAuthUI authUI: FUIAuth) -> FUIAuthPickerViewController {
  return FUICustomAuthPickerViewController(nibName: "FUICustomAuthPickerViewController",
                                           bundle: Bundle.main,
                                           authUI: authUI)
}

func emailEntryViewController(forAuthUI authUI: FUIAuth) -> FUIEmailEntryViewController {
  return FUICustomEmailEntryViewController(nibName: "FUICustomEmailEntryViewController",
                                           bundle: Bundle.main,
                                           authUI: authUI)
}

func passwordRecoveryViewController(forAuthUI authUI: FUIAuth, email: String) -> FUIPasswordRecoveryViewController {
  return FUICustomPasswordRecoveryViewController(nibName: "FUICustomPasswordRecoveryViewController",
                                                 bundle: Bundle.main,
                                                 authUI: authUI,
                                                 email: email)
}

func passwordSignInViewController(forAuthUI authUI: FUIAuth, email: String) -> FUIPasswordSignInViewController {
  return FUICustomPasswordSignInViewController(nibName: "FUICustomPasswordSignInViewController",
                                               bundle: Bundle.main,
                                               authUI: authUI,
                                               email: email)
}

func passwordSignUpViewController(forAuthUI authUI: FUIAuth, email: String) -> FUIPasswordSignUpViewController {
  return FUICustomPasswordSignUpViewController(nibName: "FUICustomPasswordSignUpViewController",
                                               bundle: Bundle.main,
                                               authUI: authUI,
                                               email: email)
}

func passwordVerificationViewController(forAuthUI authUI: FUIAuth, email: String, newCredential: AuthCredential) -> FUIPasswordVerificationViewController {
  return FUICustomPasswordVerificationViewController(nibName: "FUICustomPasswordVerificationViewController",
                                                     bundle: Bundle.main,
                                                     authUI: authUI,
                                                     email: email,
                                                     newCredential: newCredential)
}

Objective-C

- (FUIAuthPickerViewController *)authPickerViewControllerForAuthUI:(FUIAuth *)authUI {
  return [[FUICustomAuthPickerViewController alloc] initWithNibName:@"FUICustomAuthPickerViewController"
                                                             bundle:[NSBundle mainBundle]
                                                             authUI:authUI];
}

- (FUIEmailEntryViewController *)emailEntryViewControllerForAuthUI:(FUIAuth *)authUI {
  return [[FUICustomEmailEntryViewController alloc] initWithNibName:@"FUICustomEmailEntryViewController"
                                                             bundle:[NSBundle mainBundle]
                                                             authUI:authUI];

}

- (FUIPasswordSignInViewController *)passwordSignInViewControllerForAuthUI:(FUIAuth *)authUI
                                                                     email:(NSString *)email {
  return [[FUICustomPasswordSignInViewController alloc] initWithNibName:@"FUICustomPasswordSignInViewController"
                                                                 bundle:[NSBundle mainBundle]
                                                                 authUI:authUI
                                                                  email:email];

}

- (FUIPasswordSignUpViewController *)passwordSignUpViewControllerForAuthUI:(FUIAuth *)authUI
                                                                     email:(NSString *)email {
  return [[FUICustomPasswordSignUpViewController alloc] initWithNibName:@"FUICustomPasswordSignUpViewController"
                                                                 bundle:[NSBundle mainBundle]
                                                                 authUI:authUI
                                                                  email:email];

}

- (FUIPasswordRecoveryViewController *)passwordRecoveryViewControllerForAuthUI:(FUIAuth *)authUI
                                                                         email:(NSString *)email {
  return [[FUICustomPasswordRecoveryViewController alloc] initWithNibName:@"FUICustomPasswordRecoveryViewController"
                                                                   bundle:[NSBundle mainBundle]
                                                                   authUI:authUI
                                                                    email:email];

}

- (FUIPasswordVerificationViewController *)passwordVerificationViewControllerForAuthUI:(FUIAuth *)authUI
                                                                                 email:(NSString *)email
                                                                         newCredential:(FIRAuthCredential *)newCredential {
  return [[FUICustomPasswordVerificationViewController alloc] initWithNibName:@"FUICustomPasswordVerificationViewController"
                                                                       bundle:[NSBundle mainBundle]
                                                                       authUI:authUI
                                                                        email:email
                                                                newCredential:newCredential];
}

您可以自訂應用程式服務條款的網址,透過帳戶建立畫面連結:

Swift

let kFirebaseTermsOfService = URL(string: "https://example.com/terms")!
authUI.tosurl = kFirebaseTermsOfService

Objective-C

authUI.TOSURL = [NSURL URLWithString:@"https://example.com/terms"];

最後,您可以指定自訂套件,自訂要向使用者顯示的訊息和提示:

Swift

authUI.customStringsBundle = NSBundle.mainBundle() // Or any custom bundle.

Objective-C

authUI.customStringsBundle = [NSBundle mainBundle]; // Or any custom bundle.

後續步驟

  • 如要進一步瞭解如何使用及自訂 FirebaseUI,請參閱 GitHub 上的 README 檔案。
  • 如果您在 FirebaseUI 中發現並想要回報問題,請使用 GitHub 問題追蹤工具