Skip to content

Commit bc040dd

Browse files
Merge branch 'development' into api-refactor
2 parents dbfc162 + 859e364 commit bc040dd

File tree

14 files changed

+74
-116
lines changed

14 files changed

+74
-116
lines changed

FirebaseSwiftUI/FirebaseAppleSwiftUI/Sources/Services/AppleProviderAuthUI.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ extension AuthenticateWithAppleDialog: ASAuthorizationControllerDelegate {
114114

115115
// MARK: - Apple Provider Swift
116116

117-
public class AppleProviderSwift: AuthProviderSwift {
117+
public class AppleProviderSwift: CredentialAuthProviderSwift {
118118
public let scopes: [ASAuthorization.Scope]
119119
let providerId = "apple.com"
120120

@@ -140,15 +140,15 @@ public class AppleProviderSwift: AuthProviderSwift {
140140
}
141141

142142
public class AppleProviderAuthUI: AuthProviderUI {
143-
public var provider: AuthProviderSwift
143+
private let typedProvider: AppleProviderSwift
144+
public var provider: AuthProviderSwift { typedProvider }
145+
public let id: String = "apple.com"
144146

145-
public init(provider: AuthProviderSwift) {
146-
self.provider = provider
147+
public init(provider: AppleProviderSwift) {
148+
typedProvider = provider
147149
}
148150

149-
public let id: String = "apple.com"
150-
151151
@MainActor public func authButton() -> AnyView {
152-
AnyView(SignInWithAppleButton(provider: provider))
152+
AnyView(SignInWithAppleButton(provider: typedProvider))
153153
}
154154
}

FirebaseSwiftUI/FirebaseAppleSwiftUI/Sources/Views/SignInWithAppleButton.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import SwiftUI
2121
public struct SignInWithAppleButton {
2222
@Environment(AuthService.self) private var authService
2323
@Environment(\.reportError) private var reportError
24-
let provider: AuthProviderSwift
25-
public init(provider: AuthProviderSwift) {
24+
let provider: AppleProviderSwift
25+
public init(provider: AppleProviderSwift) {
2626
self.provider = provider
2727
}
2828
}

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ import FirebaseAuthUIComponents
1717
import FirebaseCore
1818
import SwiftUI
1919

20-
public protocol AuthProviderSwift {
20+
/// Base protocol for all authentication providers
21+
public protocol AuthProviderSwift {}
22+
23+
/// Protocol for providers that can directly create an AuthCredential
24+
/// Used by Google, Apple, Twitter, Facebook, and OAuth providers
25+
public protocol CredentialAuthProviderSwift: AuthProviderSwift {
2126
@MainActor func createAuthCredential() async throws -> AuthCredential
2227
}
2328

@@ -27,12 +32,6 @@ public protocol AuthProviderUI {
2732
var provider: AuthProviderSwift { get }
2833
}
2934

30-
public protocol PhoneAuthProviderSwift: AuthProviderSwift {
31-
@MainActor func verifyPhoneNumber(phoneNumber: String) async throws -> String
32-
@MainActor func createAuthCredential(verificationId: String,
33-
verificationCode: String) async throws -> AuthCredential
34-
}
35-
3635
public enum AuthenticationState {
3736
case unauthenticated
3837
case authenticating
@@ -148,10 +147,6 @@ public final class AuthService {
148147

149148
private var providers: [AuthProviderUI] = []
150149

151-
public var currentPhoneProvider: PhoneAuthProviderSwift? {
152-
providers.compactMap { $0.provider as? PhoneAuthProviderSwift }.first
153-
}
154-
155150
public func registerProvider(providerWithButton: AuthProviderUI) {
156151
providers.append(providerWithButton)
157152
}
@@ -173,7 +168,7 @@ public final class AuthService {
173168
)
174169
}
175170

176-
public func signIn(_ provider: AuthProviderSwift) async throws -> SignInOutcome {
171+
public func signIn(_ provider: CredentialAuthProviderSwift) async throws -> SignInOutcome {
177172
let credential = try await provider.createAuthCredential()
178173
let result = try await signIn(credentials: credential)
179174
return result
@@ -747,8 +742,15 @@ public extension AuthService {
747742
let password = try await passwordPrompt.confirmPassword()
748743
let credential = EmailAuthProvider.credential(withEmail: email, password: password)
749744
_ = try await user.reauthenticate(with: credential)
750-
} else if let matchingProvider = providers.first(where: { $0.id == providerId }) {
751-
let credential = try await matchingProvider.provider.createAuthCredential()
745+
} else if providerId == PhoneAuthProviderID {
746+
// Phone auth requires manual reauthentication via sign out and sign in otherwise it will take
747+
// the user out of the existing flow
748+
throw AuthServiceError.reauthenticationRequired(
749+
"Phone authentication requires you to sign out and sign in again to continue"
750+
)
751+
} else if let matchingProvider = providers.first(where: { $0.id == providerId }),
752+
let credentialProvider = matchingProvider.provider as? CredentialAuthProviderSwift {
753+
let credential = try await credentialProvider.createAuthCredential()
752754
_ = try await user.reauthenticate(with: credential)
753755
} else {
754756
throw AuthServiceError.providerNotFound("No provider found for \(providerId)")

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,8 @@ struct EnterPhoneNumberView: View {
4949
Button(action: {
5050
Task {
5151
do {
52-
guard let provider = authService.currentPhoneProvider else {
53-
fatalError("No phone provider found")
54-
}
5552
let fullPhoneNumber = selectedCountry.dialCode + phoneNumber
56-
let id = try await provider.verifyPhoneNumber(phoneNumber: fullPhoneNumber)
53+
let id = try await authService.verifyPhoneNumber(phoneNumber: fullPhoneNumber)
5754
authService.navigator.push(.enterVerificationCode(
5855
verificationID: id,
5956
fullPhoneNumber: fullPhoneNumber

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterVerificationCodeView.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,10 @@ struct EnterVerificationCodeView: View {
5353
Button(action: {
5454
Task {
5555
do {
56-
guard let provider = authService.currentPhoneProvider else {
57-
fatalError("No phone provider found")
58-
}
59-
let credential = try await provider.createAuthCredential(
60-
verificationId: verificationID,
56+
try await authService.signInWithPhoneNumber(
57+
verificationID: verificationID,
6158
verificationCode: verificationCode
6259
)
63-
64-
_ = try await authService.signIn(credentials: credential)
6560
authService.navigator.clear()
6661
} catch let caughtError {
6762
reportError(caughtError)

FirebaseSwiftUI/FirebaseFacebookSwiftUI/Sources/Services/FacebookProviderAuthUI.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import FirebaseAuth
1919
import FirebaseAuthSwiftUI
2020
import SwiftUI
2121

22-
public class FacebookProviderSwift: AuthProviderSwift {
22+
public class FacebookProviderSwift: CredentialAuthProviderSwift {
2323
let scopes: [String]
2424
let providerId = "facebook.com"
2525
private let loginManager = LoginManager()
@@ -119,14 +119,15 @@ public class FacebookProviderSwift: AuthProviderSwift {
119119
}
120120

121121
public class FacebookProviderAuthUI: AuthProviderUI {
122-
public var provider: AuthProviderSwift
122+
private let typedProvider: FacebookProviderSwift
123+
public var provider: AuthProviderSwift { typedProvider }
123124
public let id: String = "facebook.com"
124125

125-
public init(provider: AuthProviderSwift) {
126-
self.provider = provider
126+
public init(provider: FacebookProviderSwift) {
127+
typedProvider = provider
127128
}
128129

129130
@MainActor public func authButton() -> AnyView {
130-
AnyView(SignInWithFacebookButton(facebookProvider: provider as! FacebookProviderSwift))
131+
AnyView(SignInWithFacebookButton(facebookProvider: typedProvider))
131132
}
132133
}

FirebaseSwiftUI/FirebaseGoogleSwiftUI/Sources/Services/GoogleProviderAuthUI.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import GoogleSignIn
1919
import GoogleSignInSwift
2020
import SwiftUI
2121

22-
public class GoogleProviderSwift: AuthProviderSwift {
22+
public class GoogleProviderSwift: CredentialAuthProviderSwift {
2323
let scopes: [String]
2424
let clientID: String
2525
let providerId = "google.com"
@@ -71,14 +71,15 @@ public class GoogleProviderSwift: AuthProviderSwift {
7171
}
7272

7373
public class GoogleProviderAuthUI: AuthProviderUI {
74-
public var provider: AuthProviderSwift
74+
private let typedProvider: GoogleProviderSwift
75+
public var provider: AuthProviderSwift { typedProvider }
7576
public let id: String = "google.com"
7677

77-
public init(provider: AuthProviderSwift) {
78-
self.provider = provider
78+
public init(provider: GoogleProviderSwift) {
79+
typedProvider = provider
7980
}
8081

8182
@MainActor public func authButton() -> AnyView {
82-
AnyView(SignInWithGoogleButton(googleProvider: provider))
83+
AnyView(SignInWithGoogleButton(googleProvider: typedProvider))
8384
}
8485
}

FirebaseSwiftUI/FirebaseGoogleSwiftUI/Sources/Views/SignInWithGoogleButton.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ import SwiftUI
2727
public struct SignInWithGoogleButton {
2828
@Environment(AuthService.self) private var authService
2929
@Environment(\.reportError) private var reportError
30-
let googleProvider: AuthProviderSwift
30+
let googleProvider: GoogleProviderSwift
3131

32-
public init(googleProvider: AuthProviderSwift) {
32+
public init(googleProvider: GoogleProviderSwift) {
3333
self.googleProvider = googleProvider
3434
}
3535
}

FirebaseSwiftUI/FirebaseOAuthSwiftUI/Sources/Services/OAuthProviderSwift.swift

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import FirebaseCore
1818
import SwiftUI
1919

2020
/// Configuration for a generic OAuth provider
21-
public class OAuthProviderSwift: AuthProviderSwift {
21+
public class OAuthProviderSwift: CredentialAuthProviderSwift {
2222
public let providerId: String
2323
public let scopes: [String]
2424
public let customParameters: [String: String]
@@ -116,20 +116,18 @@ public class OAuthProviderSwift: AuthProviderSwift {
116116
}
117117

118118
public class OAuthProviderAuthUI: AuthProviderUI {
119-
public var provider: AuthProviderSwift
119+
private let typedProvider: OAuthProviderSwift
120+
public var provider: AuthProviderSwift { typedProvider }
120121

121-
public init(provider: AuthProviderSwift) {
122-
self.provider = provider
122+
public init(provider: OAuthProviderSwift) {
123+
typedProvider = provider
123124
}
124125

125126
public var id: String {
126-
guard let oauthProvider = provider as? OAuthProviderSwift else {
127-
return "oauth.unknown"
128-
}
129-
return oauthProvider.providerId
127+
return typedProvider.providerId
130128
}
131129

132130
@MainActor public func authButton() -> AnyView {
133-
AnyView(GenericOAuthButton(provider: provider))
131+
AnyView(GenericOAuthButton(provider: typedProvider))
134132
}
135133
}

FirebaseSwiftUI/FirebaseOAuthSwiftUI/Sources/Views/GenericOAuthButton.swift

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,28 @@ import SwiftUI
2121
public struct GenericOAuthButton {
2222
@Environment(AuthService.self) private var authService
2323
@Environment(\.reportError) private var reportError
24-
let provider: AuthProviderSwift
25-
public init(provider: AuthProviderSwift) {
24+
let provider: OAuthProviderSwift
25+
public init(provider: OAuthProviderSwift) {
2626
self.provider = provider
2727
}
2828
}
2929

3030
extension GenericOAuthButton: View {
3131
public var body: some View {
32-
guard let oauthProvider = provider as? OAuthProviderSwift else {
33-
return AnyView(
34-
Text(authService.string.invalidOAuthProviderError)
35-
.foregroundColor(.red)
36-
)
37-
}
38-
3932
// Create custom style from provider configuration
4033
var resolvedStyle: ProviderStyle {
4134
ProviderStyle(
42-
icon: oauthProvider.buttonIcon,
43-
backgroundColor: oauthProvider.buttonBackgroundColor,
44-
contentColor: oauthProvider.buttonForegroundColor
35+
icon: provider.buttonIcon,
36+
backgroundColor: provider.buttonBackgroundColor,
37+
contentColor: provider.buttonForegroundColor
4538
)
4639
}
4740

4841
return AnyView(
4942
AuthProviderButton(
50-
label: oauthProvider.displayName,
43+
label: provider.displayName,
5144
style: resolvedStyle,
52-
accessibilityId: "sign-in-with-\(oauthProvider.providerId)-button"
45+
accessibilityId: "sign-in-with-\(provider.providerId)-button"
5346
) {
5447
Task {
5548
do {

0 commit comments

Comments
 (0)