RxFireAuth
RxFireAuth 是 Firebase Authentication SDK 的封装,通过 RxSwift 对象公开了大部分可用功能,同时改善了管理并处理账户的整个应用程序生命周期中的逻辑。
Firebase Authentication 是一种支持应用程序中用户身份验证的简单方法。这个库在此基础上,通过预构建的算法进一步简化了注册、登录、与其他提供商链接账户等过程。
寻找 Android 版本?您可以在 这里 找到它。
安装
RxFireAuth 通过 CocoaPods 和 Swift Package Manager 提供。
如果您想在需要为 Apple Silicon 构建的项目中包含此库,强烈建议使用 SPM。
CocoaPods
要将 RxFireAuth 添加到项目中,请添加
pod 'RxFireAuth'
Swift包管理器
要在项目中安装RxFireAuth,请使用Xcode将此存储库作为依赖项添加,或者在您的Package.swift
文件中添加以下内容
.package(url: "https://github.com/MrAsterisco/RxFireAuth", from: "<see GitHub releases>")
Google Sign In SDK不通过Swift包管理器提供,并且会被自动替换为AppAuth的标准实现。
最新版本
要查找最新版本,请查看此存储库的“发布”标签。
开始使用
要开始使用RxFireAuth,您可以下载示例项目或直接查看文档。
示例项目
此库包含一个示例项目,展示了如何在iOS和macOS上实现库的所有功能。
要查看实际功能,请按照以下步骤操作
- 下载此存储库。
- 转到您的Firebase控制台并创建一个新的项目(免费!)
- 添加两个iOS应用,拥有以下包标识符:
io.mrasterisco.github.RxFireAuth-Example
和io.mrasterisco.github.RxFireAuth-Example-macOS
。如果您不想在两个平台上同时使用,也可以只添加其中一个。 - 为每个平台下载
GoogleService-Info.plist
文件,并分别将其放置在Example/RxFireAuth
目录下(iOS)和Example\RxFireAuth macOS
目录下(macOS) - 在Firebase控制台中,转到身份验证标签并启用“电子邮件/密码”、“匿名”、“Apple”和“Google”
使用 CocoaPods 进行测试
- 导航到
Example
文件夹并运行pod install
。 - 打开
RxFireAuth.xcworkspace
,选择一个有效的签名身份,构建并运行。
使用 Swift 包管理器进行测试
- 在
Example-SwiftPM
文件夹下打开RxFireAuth.xcodeproj
。
注意:Firebase 控制台不支持 macOS 应用程序,因此您必须将 macOS 版本添加为 iOS 应用程序。请注意,Firebase SDK for macOS 不是 Firebase 产品的官方组成部分,但它得到了社区支持。您可以在以下链接中找到更多信息:这里。
注意 2:要测试 Sign in with Apple,您需要一个有效的签名身份。如果您现在没有,您可以在 Xcode 项目的“签名与能力”选项卡中关闭 Sign in with Apple。
参考资料
整个库都是围绕 UserManagerType
协议构建的。库通过 UserManager
类提供了它的默认实现,您可以直接实例化它或通过依赖注入获取它。
配置
RxFireAuth 假定您已经阅读过 Firebase 身份验证文档网站上的 入门指南。这意味着
- 您已经在 Firebase 控制台中创建了一个新的项目。
- 您已经 注册了您的应用程序的打包标识符并 添加了
GoogleService-Info.plist
文件。 - 您已经在应用启动时配置了Firebase SDK:-- iOS:您已在AppDelegate中的
application:didFinishLaunchingWithOptions:
函数中调用了FirebaseApp.configure()
,详情请参阅此处。-- macOS:您已在AppDelegate中的awakeFromNib
函数中调用了FirebaseApp.configure()
。 - 您已经在Firebase控制台中打开了并配置了您想要使用的认证提供者。
在您的Podfile中,您可以省略Firebase/Auth
的引用,因为它是这个库的依赖项,并会自动包含。
OAuth提供者
要支持例如Google SignIn之类的OAuth提供者,您还需要在您的AppDelegate
中添加以下代码:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return self.userManager.loginHandler?.handle(url: url) ?? false
}
或者,如果您在macOS上使用库,那么请向您的AppDelegate
添加以下代码:
func applicationDidFinishLaunching(_ notification: Notification) {
NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(AppDelegate.handleGetURLEvent(event:replyEvent:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
}
@objc func handleGetURLEvent(event: NSAppleEventDescriptor, replyEvent: NSAppleEventDescriptor) {
let urlString = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject))?.stringValue!
let url = URL(string: urlString!)!
_ = userManager.loginHandler?.handle(url: url)
}
您还必须在Info.plist
中注册您应用的回调URL。
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>{{FIREBASE_REVERSED_CLIENT_ID}}</string>
</array>
</dict>
</array>
您可以在GoogleService-Info.plist
文件中找到您的FIREBASE_REVERSED_CLIENT_ID
。
功能
RxFireAuth提供了多种简单的反应式方式来与Firebase Authentication交互。
登录
RxFireAuth的目标之一是简化构建易于无缝使用的新用户和回应用户的注册/登录屏幕,同时考虑Firebase创建匿名账户的能力。
匿名账户流程
现代应用应该尽可能推迟登录。来自苹果人类界面指南
尽可能推迟登录。人们经常在无法进行任何有用的操作之前被迫登录而放弃应用。在承诺之前,给他们一个熟悉您应用的机会。例如,一个实时流媒体应用可以在用户登录以进行流式传输之前,允许他们探索可用内容。
匿名账户是 Firebase 支持这种情况的方式:当您首次启动应用时,您将创建一个匿名账户,这样当用户准备好登录时,可以将其转换为新的账户。这对新账户工作得非常完美,但在处理回头客时有几个需要注意的问题。
考虑以下情况
- Mike 是您应用的全新用户。由于您在 Mike 打开您的应用时严格遵守了 Apple 的指导原则,他直接进入了主屏幕。
- Mike 在您的应用中建立的所有数据都链接到一个您在首次启动应用时自动创建的匿名账户。
- 在某个时候,Mike 决定登录,以便将他的数据与另一台设备同步。他使用电子邮件和一个密码注册了新的账户。
- 到目前为止,使用正常的 Firebase SDK 一切看起来都很不错,除非您对 RxSwift 非常感兴趣,并且希望将所有 Firebase 方法包装成 Rx 组件;如果是这种情况,请跳过下面的几个点,直接跳转到“代码展示”部分。
- 现在,Mike 想要使用他崭新的账户在其他设备上登录。他重新下载了应用,并发现自己出现在主屏幕上。
- 他直接进入登录屏幕,输入他的账户凭证:此时,使用 Firebase SDK,您将尝试将应用启动时创建的匿名账户与 Mike 的凭证链接起来,但您将收到一个错误,表明这些凭证已经被使用。**这里是这个库能帮到您的地方:登录时,UserManager 类将自动检查指定的凭证是否已经存在,并使用这些凭证进行登录;它还会删除不再需要的匿名账户,并将一切反馈给您**。
代码展示
使用以下方法使用电子邮件和密码登录
func login(email: String, password: String, allowMigration: Bool?) -> Single<LoginDescriptor>
在本文描述的情况中,allowMigration
参数非常有用:有一个匿名账户需要删除并用现有账户替换。当设置为 nil
时,库将返回一个 Single
,它发出 UserError.migrationRequired
错误,以便您的应用有机会询问用户他们想如何处理匿名账户中的数据。
用户做出选择后,将 true
或 false
传递到代码,以在登录过程成功完成后将相同的值返回给您的代码。
为了支持迁移,所有登录方法都返回一个 LoginDescriptor
实例,其中包含您传递的 allowMigration
参数、匿名账户的用户 ID 以及当前登录账户的用户 ID。有了这些信息,您就可以将匿名账户中的数据迁移到新登录的账户了。
使用认证提供商登录
如果您考虑为应用提供其他登录方式,RxFireAuth为您提供全面支持。
在外部提供程序中登录时,总是最好让用户先登录,稍后再确定这是他们的首次登录。此外,允许人们连接不同的提供程序,同时提供电子邮件和密码凭据是一种常见的做法。给人们灵活性总是明智的选择。
让我们用之前的同一个简短的故事,但现在Mike将要使用Apple登录。
- 在第一台设备上,没有变化:使用标准的Firebase SDK,我们可以将匿名账户与Mike的Apple ID关联起来。
- 在第二台设备上,会发生两件事:首先,Apple为已经使用过Apple登录的已应用程序提供不同的流程;这不是您可以控制的,所以如果用户在您的应用程序中注册并删除其账户,当他们再次回到应用并使用Apple登录时,他们仍然会获得不同的登录流程(更多关于此的信息 这里)。其次,您必须处理各种情况。
使用Apple登录 (或任何其他提供程序,如Google)时,您会遇到以下情况之一:
- 有一个匿名用户已登录,Apple ID尚未与任何现有账户关联:太棒了!我们将只需将Apple ID与匿名用户关联,即可完成任务。
- 有一个匿名用户已登录,但Apple ID已经与另一个账户关联:我们将进行迁移,然后登录到现有账户。
- 有一个正常用户已登录,Apple ID尚未与任何其他账户关联:该用户试图将其Apple ID与其现有账户关联,让我们先完成这个。
- 有一个正常用户已登录,但Apple ID已经与另一个账户关联:我们将抛出错误,因为用户必须选择要做什么。
- 没有任何用户登录,Apple ID可能已经关联或未关联:我们将登录到现有或新账户。
使用RxFireAuth的login
方法家族,所有这些情况都由您自动处理。
代码展示
通过调用自动处理所有可能的情况
func signInWithApple(in viewController: UIViewController, updateUserDisplayName: Bool, allowMigration: Bool?) -> Single<LoginDescriptor>
或
func signInWithGoogle(as clientId: String, in viewController: UIViewController, updateUserDisplayName: Bool, allowMigration: Bool?) -> Single<LoginDescriptor>
这些函数在LoginProviderManagerType
的实现中可用,例如我们已经在使用的UserManager
类。
您可以使用updateUserDisplayName
参数自动将Firebase User的displayName
属性设置为与提供程序账户关联的全名。请注意,一些供应商,如Apple,允许用户在首次登录时更改此信息,并且仅对新用户返回,这些用户以前从未登录过您的应用程序。
此函数将像正常签名一样执行,如果匿名账号需要被删除且未设置 allowMigration
,将返回 UserError.migrationRequired
。在这种情况下,您可以使用以下函数在询问用户想要做什么后继续登录。
func login(with credentials: LoginCredentials, updateUserDisplayName: Bool, allowMigration: Bool?) -> Single<LoginDescriptor>
登录凭证包含在 migrationRequired
错误中,除非是特殊情况,否则您不需要检查它们。
用户数据
您可以通过调用以下方法来获取当前登录用户的配置文件
self.userManager.user
或通过订阅以下内容
self.userManager.autoupdatingUser
此可观察对象将在用户配置文件发生变化时发出新值。
登录后,您可以通过遍历 UserData
实例的 authenticationProviders
数组来检查用户的认证提供程序。有关支持提供程序列表,请参阅 LoginCredentials
中的 Provider
枚举。
认证确认
在进行敏感操作,如更改用户密码、链接新的认证提供程序或删除用户账号时,Firebase 会要求您通过强制用户重新登录来获取新的刷新令牌。RxFireAuth 提供方便的方法,通过支持提供的提供程序之一来确认认证。
您可以使用电子邮件和密码进行认证确认
func confirmAuthentication(email: String, password: String) -> Completable
使用 Apple 登录
func confirmAuthenticationWithApple(in viewController: UIViewController) -> Completable
或使用 Google 登录
func confirmAuthenticationWithGoogle(as clientId: String, in viewController: UIViewController) -> Completable
文档
请始终在您的代码中参考 UserManagerType
和 LoginProviderManagerType
协议,因为即使库的主版本没有更改,UserManager
实现也可能引入破坏性的更改。
这些协议已完整文档化,如所有相关的结构和帮助类。
您可以在以下位置找到自动生成的文档:https://mrasterisco.github.io/RxFireAuth/。
兼容性
RxFireAuth 与 iOS、macOS 和 Mac Catalyst 兼容。
RxFireAuth 的目标是 iOS 11.0 或更高版本 和 macOS 10.12 或更高版本,并具有以下共享依赖项
Firebase/Auth
版本 8。JWTDecode
版本 2。RxCocoa
版本 6。AppAuth
版本 1。
贡献
欢迎所有为扩展库做出贡献的朋友。请 Fork 仓库,进行您需要的改动,并提交 Pull Request。
如果您修改了代码库,我并不会强制要求特定的编码风格,但我可能要求您根据库的其他部分进行更改。
状态
该库处于 积极开发 状态。它在多个生产中的应用中都有使用。
尽管大多数 API 相当直观,但它们在未来可能会有变化;但您不必担心这一点,因为发布将遵循 语义化版本控制 2.0.0。
许可
RxFireAuth 采用 MIT 许可证进行分发。请参阅 LICENSE 以获取详细信息。