الانتقال إلى وحدة التحكم

使用 FirebaseUI 轻松向 iOS 应用添加登录服务

FirebaseUI 是以 Firebase Authentication SDK 为基础构建的库,提供适合在您应用中使用的普适性界面流程。FirebaseUI 具有以下优势:

  • 多提供商:用于电子邮件地址/密码身份验证、电子邮件链接身份验证、电话身份验证、Google 登录机制、Facebook 登录机制和 Twitter 登录机制的登录流程。
  • 帐号管理:用于处理帐号管理任务(如帐号创建和密码重置)的流程。
  • 匿名帐号关联 :用于自动将匿名帐号关联到身份提供商的流程。
  • 可自定义:自定义 FirebaseUI 的外观以使其与您的应用相匹配。另外,FirebaseUI 是开源的,因此您可以克隆 (fork) 项目并对其进行自定义,使之完全符合您的需求。

准备工作

  1. 将 Firebase 添加到您的 iOS 项目

  2. 将 FirebaseUI 添加到您的 Podfile:

    pod 'FirebaseUI'
    

    根据您的个人喜好,您可以只添加身份验证组件及您想要使用的提供方:

    pod 'FirebaseUI/Auth'
    
    pod 'FirebaseUI/Google'
    pod 'FirebaseUI/Facebook'
    pod 'FirebaseUI/Twitter'
    pod 'FirebaseUI/Phone'
    
  3. 如果您尚未将您的应用与 Firebase 项目相关联,请在 Firebase 控制台中进行关联。

设置登录方法

您必须先启用并配置您希望支持的登录方法,然后用户才能通过 Firebase 登录。

电子邮件地址和密码

Firebase 控制台中,打开 Authentication(身份验证)部分并启用电子邮件地址和密码身份验证。

  1. Firebase 控制台中,打开 Authentication(身份验证)部分。在登录方法标签中,启用电子邮件地址/密码提供方。请注意,必须启用电子邮件/密码登录才能使用电子邮件链接登录。

  2. 在同一部分中,启用电子邮件链接(无密码登录)登录方法,然后点击保存

  3. 您可以初始化一个 FUIEmailAuth 实例并通过 FIREmailLinkAuthSignInMethod 来启用电子邮件链接登录。您还需要提供一个有效的 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.initAuthAuthUI(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] initAuthAuthUI:[FUIAuth defaultAuthUI]
                                                       signInMethod:FIREmailLinkAuthSignInMethod
                                                    forceSameDevice:NO
                                              allowNewEmailAccounts:YES
                                                  actionCodeSetting:actionCodeSettings];
  1. 此外,您需要将您传递给初始化程序的网址列入白名单。具体方法是在 Firebase 控制台中,打开 Authentication(身份验证)部分。在登录方法标签页上,在已获授权的网域下添加该网址。

  2. 捕获深层链接后,您需要将其传递至身份验证界面,以便进行处理。

Swift

Auth.defaultAuthUI.handleOpenURL(url, sourceApplication: sourceApplication)

Objective-C

[FUIAuth.defaultAuthUI handleOpenURL:url sourceApplication:sourceApplication];
  1. FirebaseUI-iOS 中的电子邮件链接登录方法与 FirebaseUI-AndroidFirebaseUI-web 兼容(在这种情况下,一个从 FirebaseUI-Android 启动该流程的用户可以打开链接并使用 FirebaseUI-web 完成登录)。对于反向流程也是如此。

Google

  1. Firebase 控制台中,打开 Authentication(身份验证)部分并启用 Google 登录服务。

  2. 在您的 Xcode 项目中,将您的倒序客户端 ID 添加为网址架构。您可以在 GoogleService-Info.plist 文件中找到这个值。

Facebook

  1. 按照 Facebook 的使用入门页面来设置 Facebook 登录 SDK。

  2. Firebase 控制台中,打开 Authentication(身份验证)部分并启用 Facebook 登录服务。要启用 Facebook 登录机制,您必须提供您的 Facebook 应用 ID 和应用密钥,这些信息可在 Facebook 开发者控制台中找到。

  3. 在您的 Xcode 项目中,依次点击项目设置 > 功能,然后在相应屏幕中启用密钥链共享。

  4. 在您的 Xcode 项目中,将 fbFACEBOOK_APP_ID 添加为网址架构。

  5. 将您的 Facebook 应用 ID 和显示名添加至 Info.plist 文件中:

    FacebookAppID FACEBOOK_APP_ID(例如 1234567890
    FacebookDisplayName 您的应用的名称

Twitter

  1. Firebase 控制台中,打开 Authentication(身份验证)部分并启用 Twitter 登录服务。要启用 Twitter 登录服务,您必须提供您的 Twitter API 使用方密钥和密文,这些信息可在 Twitter Application Management 控制台中找到。

  2. 初始化为 Twitter 登录服务配置的 OAuth 提供方实例:

    Swift

    provider = FUIOAuth(authUI: self.authUI!,
                    providerID: "twitter.com",
                    buttonLabelText: "Sign in with Twitter",
                    shortName: "Twitter",
                    buttonColor: buttonColor,
                    iconImage: UIImage(contentsOfFile: iconPath)!,
                    scopes: ["user.readwrite"],
                    customParameters: ["prompt" : "consent"],
                    loginHintKey: nil)
    

    Objective-C

    FUIOAuth *provider = [[FUIOAuth alloc] initWithAuthUI:[FUIAuth defaultAuthUI]
                                           providerID:@"twitter.com"
                                      buttonLabelText:@"Sign in with Twitter"
                                            shortName:@"Twitter"
                                          buttonColor:buttonColor
                                            iconImage:[UIImage imageWithContentsOfFile:iconPath]
                                               scopes:@[@"user.readwrite"]
                                     customParameters:@{@"prompt" : @"consent"}
                                         loginHintKey:nil];
    

电话号码

  1. Firebase 控制台中,打开 Authentication(身份验证)部分并启用电话号码登录服务。

  2. Firebase 必须要能验证电话号码登录请求是否来自于您的应用。实现这一目的的方法之一是通过 APNs 通知。如需了解详情,请参阅启用应用验证

    启用 APNs 通知以用于 Firebase 身份验证:

    1. 在 Xcode 中为您的项目启用推送通知

    2. 将您的 APNs 身份验证密钥上传到 Firebase。如果您还没有 APNs 身份验证密钥,请参阅配置 FCM APNs

      1. 在 Firebase 控制台中,在您的项目内依次选择齿轮图标、项目设置以及云消息传递标签。

      2. iOS 应用配置下的 APNs 身份验证密钥中,点击上传按钮。

      3. 转到您保存密钥的位置,选择该密钥,然后点击打开。添加该密钥的 ID(可在 Apple Developer Member CenterCertificates, Identifiers & Profiles 中找到),然后点击上传

      如果您已有 APNs 证书,可以改为上传该证书。

  3. 如果设备无法接收 APNs 通知,Firebase 会使用 reCAPTCHA 来验证请求。

    如果要启用 reCAPTCHA 验证,但您尚未将您的倒序客户端 ID 作为网址架构添加(例如为了启用 Google 登录机制),请在您的 Xcode 项目中添加。您可以在 GoogleService-Info.plist 文件中找到这个值。

  4. 可选:Firebase 使用方法调配 (method swizzling) 自动获取您的应用的 APNs 令牌,以便处理 Firebase 发送给您应用的静默推送通知,以及在验证期间自动拦截来自 reCAPTCHA 验证页面的自定义架构重定向。

    如果您不想使用调配,请参阅 Firebase SDK 身份验证文档中的附录:使用电话登录而不调配

登录

要启动 FirebaseUI 登录流程,首先应初始化 FirebaseUI:

Swift

import FirebaseUI

/* ... */

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

Objective-C

@import FirebaseUI;

...

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

然后,配置 FirebaseUI 以使用您希望支持的登录方法:

Swift

import FirebaseUI

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

Objective-C

@import FirebaseUI;

...

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"];

最后,您可以通过指定自定义 bundle 的方式来自定义向用户显示的消息和提示:

Swift

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

Objective-C

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

后续步骤

  • 如需详细了解如何使用和自定义 FirebaseUI,请参阅 GitHub 上的 README 文件。
  • 如果您发现 FirebaseUI 中存在问题并想报告,请使用 GitHub 问题跟踪器