From cb7274016118d30a5ac70f1d8e1a2e164e3c0032 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Fri, 9 May 2025 13:04:54 +0100 Subject: [PATCH 1/4] refactor: email sign-in opt-in, remove providerButton closure --- .../Sources/Services/AuthService.swift | 7 +++ .../Sources/Utils/StringUtils.swift | 2 + .../Sources/Views/AuthPickerView.swift | 47 ++++++++++--------- .../FirebaseSwiftUIExample/ContentView.swift | 5 +- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift index c26fed3635..8d1c87c55f 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift @@ -90,6 +90,8 @@ public final class AuthService { private var listenerManager: AuthListenerManager? private var signedInCredential: AuthCredential? + var emailSignInEnabled = false + private var providers: [ExternalAuthProvider] = [] public func register(provider: ExternalAuthProvider) { providers.append(provider) @@ -256,6 +258,11 @@ public extension AuthService { // MARK: - Email/Password Sign In public extension AuthService { + func withEmailSignIn() -> AuthService { + emailSignInEnabled = true + return self + } + func signIn(withEmail email: String, password: String) async throws { let credential = EmailAuthProvider.credential(withEmail: email, password: password) try await signIn(credentials: credential) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift index 170632b512..5855c00563 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift @@ -308,12 +308,14 @@ public class StringUtils { public var enterPhoneNumberLabel: String { return localizedString(for: "Enter phone number") } + /// Phone provider /// found in: /// - PhoneAuthButtonView public var phoneNumberVerificationCodeLabel: String { return localizedString(for: "Enter verification code") } + /// Phone provider /// found in: /// - PhoneAuthButtonView diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift index 232e853aef..1a9f5ee25c 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift @@ -1,13 +1,10 @@ import SwiftUI @MainActor -public struct AuthPickerView { +public struct AuthPickerView { @Environment(AuthService.self) private var authService - let providerButtons: () -> Content - public init(@ViewBuilder providerButtons: @escaping () -> Content) { - self.providerButtons = providerButtons - } + public init() {} private func switchFlow() { authService.authenticationFlow = authService @@ -29,28 +26,32 @@ extension AuthPickerView: View { } else if authService.authView == .emailLink { EmailLinkView() } else { - Text(authService.authenticationFlow == .login ? authService.string - .emailLoginFlowLabel : authService.string.emailSignUpFlowLabel) - VStack { Divider() } - EmailAuthView() + if authService.emailSignInEnabled { + Text(authService.authenticationFlow == .login ? authService.string + .emailLoginFlowLabel : authService.string.emailSignUpFlowLabel) + VStack { Divider() } + EmailAuthView() + } authService.renderButtons() - VStack { Divider() } - HStack { - Text(authService - .authenticationFlow == .login ? authService.string.dontHaveAnAccountYetLabel : - authService.string.alreadyHaveAnAccountLabel) - Button(action: { - withAnimation { - switchFlow() + if authService.emailSignInEnabled { + VStack { Divider() } + HStack { + Text(authService + .authenticationFlow == .login ? authService.string.dontHaveAnAccountYetLabel : + authService.string.alreadyHaveAnAccountLabel) + Button(action: { + withAnimation { + switchFlow() + } + }) { + Text(authService.authenticationFlow == .signUp ? authService.string + .emailLoginFlowLabel : authService.string.emailSignUpFlowLabel) + .fontWeight(.semibold) + .foregroundColor(.blue) } - }) { - Text(authService.authenticationFlow == .signUp ? authService.string - .emailLoginFlowLabel : authService.string.emailSignUpFlowLabel) - .fontWeight(.semibold) - .foregroundColor(.blue) } + Text(authService.errorMessage).foregroundColor(.red) } - Text(authService.errorMessage).foregroundColor(.red) } } } diff --git a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/ContentView.swift b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/ContentView.swift index 9547de0308..149df5814e 100644 --- a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/ContentView.swift +++ b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/ContentView.swift @@ -34,11 +34,10 @@ struct ContentView: View { .withGoogleSignIn() .withFacebookSignIn() .withPhoneSignIn() + .withEmailSignIn() } var body: some View { - AuthPickerView { - PhoneAuthButtonView() - }.environment(authService) + AuthPickerView().environment(authService) } } From 2d8ce097106abf06026a29d8f2cd537df1440c9d Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Fri, 9 May 2025 13:13:22 +0100 Subject: [PATCH 2/4] chore: fix incorrect view --- .../FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift index 02bb970749..de26519813 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift @@ -127,7 +127,7 @@ extension EmailAuthView: View { .frame(maxWidth: .infinity) .buttonStyle(.borderedProminent) Button(action: { - authService.authView = .passwordRecovery + authService.authView = .emailLink }) { Text(authService.string.signUpWithEmailLinkButtonLabel) } From d13aea63bf1e2c0c80af61820969f34a90b28fca Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 14 May 2025 10:19:04 +0100 Subject: [PATCH 3/4] chore: rm unneeded VStack around Dividers --- .../Sources/Views/AuthPickerView.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift index 70a574c1f2..b9842eae8a 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift @@ -1,3 +1,4 @@ +import FirebaseCore import SwiftUI @MainActor @@ -29,14 +30,14 @@ extension AuthPickerView: View { if authService.emailSignInEnabled { Text(authService.authenticationFlow == .login ? authService.string .emailLoginFlowLabel : authService.string.emailSignUpFlowLabel) - VStack { Divider() } + Divider() EmailAuthView() } VStack { authService.renderButtons() }.padding(.horizontal) if authService.emailSignInEnabled { - VStack { Divider() } + Divider() HStack { Text(authService .authenticationFlow == .login ? authService.string.dontHaveAnAccountYetLabel : @@ -59,3 +60,10 @@ extension AuthPickerView: View { } } } + +#Preview { + FirebaseOptions.dummyConfigurationForPreview() + let authService = AuthService() + .withEmailSignIn() + return AuthPickerView().environment(authService) +} From 10bdd3e527844eb637d165477682f0c0643ba52d Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 14 May 2025 10:19:16 +0100 Subject: [PATCH 4/4] format --- .../FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift index b9842eae8a..cb753567fb 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift @@ -37,7 +37,7 @@ extension AuthPickerView: View { authService.renderButtons() }.padding(.horizontal) if authService.emailSignInEnabled { - Divider() + Divider() HStack { Text(authService .authenticationFlow == .login ? authService.string.dontHaveAnAccountYetLabel : @@ -64,6 +64,6 @@ extension AuthPickerView: View { #Preview { FirebaseOptions.dummyConfigurationForPreview() let authService = AuthService() - .withEmailSignIn() + .withEmailSignIn() return AuthPickerView().environment(authService) }