User+Combine.swift 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Copyright 2021 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #if canImport(Combine) && swift(>=5.0)
  15. import Combine
  16. import FirebaseAuth
  17. @available(swift 5.0)
  18. @available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)
  19. public extension User {
  20. /// Associates a user account from a third-party identity provider with this user and
  21. /// returns additional identity provider data.
  22. ///
  23. /// The publisher will emit events on the **main** thread.
  24. ///
  25. /// - Parameter credential: The credential for the identity provider.
  26. /// - Returns: A publisher that emits an `AuthDataResult` when the association flow completed
  27. /// successfully, or an error otherwise. The publisher will emit on the *main* thread.
  28. /// - Remark: Possible error codes:
  29. /// - `FIRAuthErrorCodeProviderAlreadyLinked` - Indicates an attempt to link a provider of a type
  30. /// already linked to this account.
  31. /// - `FIRAuthErrorCodeCredentialAlreadyInUse` - Indicates an attempt to link with a credential
  32. /// that has already been linked with a different Firebase account.
  33. /// - `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts with the identity provider
  34. /// represented by the credential are not enabled. Enable them in the Auth section of the Firebase console.
  35. ///
  36. /// See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods.
  37. func link(with credential: AuthCredential) -> Future<AuthDataResult, Error> {
  38. Future<AuthDataResult, Error> { promise in
  39. self.link(with: credential) { authDataResult, error in
  40. if let error = error {
  41. promise(.failure(error))
  42. } else if let authDataResult = authDataResult {
  43. promise(.success(authDataResult))
  44. }
  45. }
  46. }
  47. }
  48. /// Renews the user's authentication tokens by validating a fresh set of credentials supplied
  49. /// by the user and returns additional identity provider data.
  50. ///
  51. /// The publisher will emit events on the **main** thread.
  52. ///
  53. /// - Parameter credential: A user-supplied credential, which will be validated by the server. This can be
  54. /// a successful third-party identity provider sign-in, or an email address and password.
  55. /// - Returns: A publisher that emits an `AuthDataResult` when the reauthentication flow completed
  56. /// successfully, or an error otherwise.
  57. /// - Remark: If the user associated with the supplied credential is different from the current user, or if the validation
  58. /// of the supplied credentials fails; an error is returned and the current user remains signed in.
  59. ///
  60. /// Possible error codes:
  61. ///
  62. /// - `FIRAuthErrorCodeInvalidCredential` - Indicates the supplied credential is invalid.
  63. /// This could happen if it has expired or it is malformed.
  64. /// - `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts with the
  65. /// identity provider represented by the credential are not enabled. Enable them in the
  66. /// Auth section of the Firebase console.
  67. /// - `FIRAuthErrorCodeEmailAlreadyInUse` - Indicates the email asserted by the credential
  68. /// (e.g. the email in a Facebook access token) is already in use by an existing account,
  69. /// that cannot be authenticated with this method. Call fetchProvidersForEmail for
  70. /// this user’s email and then prompt them to sign in with any of the sign-in providers
  71. /// returned. This error will only be thrown if the "One account per email address"
  72. /// setting is enabled in the Firebase console, under Auth settings. Please note that the
  73. /// error code raised in this specific situation may not be the same on Web and Android.
  74. /// - `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled.
  75. /// - `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted reauthentication with
  76. /// an incorrect password, if credential is of the type EmailPasswordAuthCredential.
  77. /// - `FIRAuthErrorCodeUserMismatch` - Indicates that an attempt was made to
  78. /// reauthenticate with a user which is not the current user.
  79. /// - `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed.
  80. ///
  81. /// See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods.
  82. func reauthenticate(with credential: AuthCredential) -> Future<AuthDataResult, Error> {
  83. Future<AuthDataResult, Error> { promise in
  84. self.reauthenticate(with: credential) { authDataResult, error in
  85. if let error = error {
  86. promise(.failure(error))
  87. } else if let authDataResult = authDataResult {
  88. promise(.success(authDataResult))
  89. }
  90. }
  91. }
  92. }
  93. /// Disassociates a user account from a third-party identity provider with this user.
  94. ///
  95. /// The publisher will emit events on the **main** thread.
  96. ///
  97. /// - Parameter provider: The provider ID of the provider to unlink.
  98. /// - Returns: A publisher that emits a `User` when the disassociation flow completed
  99. /// successfully, or an error otherwise. The publisher will emit on the *main* thread.
  100. ///
  101. /// Possible error codes:
  102. ///
  103. /// - `FIRAuthErrorCodeNoSuchProvider` - Indicates an attempt to unlink a provider
  104. /// that is not linked to the account.
  105. /// - `FIRAuthErrorCodeRequiresRecentLogin` - Updating email is a security sensitive
  106. /// operation that requires a recent login from the user. This error indicates the user
  107. /// has not signed in recently enough. To resolve, reauthenticate the user by invoking
  108. /// reauthenticateWithCredential:completion: on `FIRUser`.
  109. ///
  110. /// See `FIRAuthErrors` for a list of error codes that are common to all `FIRUser` methods.
  111. func unlink(fromProvider provider: String) -> Future<User, Error> {
  112. Future<User, Error> { promise in
  113. self.unlink(fromProvider: provider) { user, error in
  114. if let user = user {
  115. promise(.success(user))
  116. } else if let error = error {
  117. promise(.failure(error))
  118. }
  119. }
  120. }
  121. }
  122. /// Initiates email verification for the user.
  123. ///
  124. /// The publisher will emit events on the **main** thread.
  125. ///
  126. /// - Returns: A publisher that emits no type when the verification flow completed
  127. /// successfully, or an error otherwise.
  128. ///
  129. /// Possible error codes:
  130. ///
  131. /// - `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was
  132. /// sent in the request.
  133. /// - `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in
  134. /// the console for this action.
  135. /// - `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for
  136. /// sending update email.
  137. /// - `FIRAuthErrorCodeUserNotFound` - Indicates the user account was not found.
  138. ///
  139. /// See `FIRAuthErrors` for a list of error codes that are common to all `FIRUser` methods.
  140. func sendEmailVerification() -> Future<Void, Error> {
  141. Future<Void, Error> { promise in
  142. self.sendEmailVerification { error in
  143. if let error = error {
  144. promise(.failure(error))
  145. } else {
  146. promise(.success(()))
  147. }
  148. }
  149. }
  150. }
  151. /// Initiates email verification for the user.
  152. ///
  153. /// The publisher will emit events on the **main** thread.
  154. ///
  155. /// - Parameter actionCodeSettings: An `FIRActionCodeSettings` object containing settings related to
  156. /// handling action codes.
  157. /// - Returns: A publisher that emits no type when the verification flow completed
  158. /// successfully, or an error otherwise.
  159. ///
  160. /// Possible error codes:
  161. ///
  162. /// - `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was
  163. /// sent in the request.
  164. /// - `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in
  165. /// the console for this action.
  166. /// - `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for
  167. /// sending update email.
  168. /// - `FIRAuthErrorCodeUserNotFound` - Indicates the user account was not found.
  169. /// - `FIRAuthErrorCodeMissingIosBundleID` - Indicates that the iOS bundle ID is missing when
  170. /// a iOS App Store ID is provided.
  171. /// - `FIRAuthErrorCodeMissingAndroidPackageName` - Indicates that the android package name
  172. /// is missing when the `androidInstallApp` flag is set to true.
  173. /// - `FIRAuthErrorCodeUnauthorizedDomain` - Indicates that the domain specified in the
  174. /// continue URL is not allowlisted in the Firebase console.
  175. /// - `FIRAuthErrorCodeInvalidContinueURI` - Indicates that the domain specified in the
  176. /// continue URI is not valid.
  177. func sendEmailVerification(with actionCodeSettings: ActionCodeSettings)
  178. -> Future<Void, Error> {
  179. Future<Void, Error> { promise in
  180. self.sendEmailVerification(with: actionCodeSettings) { error in
  181. if let error = error {
  182. promise(.failure(error))
  183. } else {
  184. promise(.success(()))
  185. }
  186. }
  187. }
  188. }
  189. }
  190. #endif // canImport(Combine) && swift(>=5.0)