Skip to content

feat: init SwiftUI library for FirebaseAuthSwiftUI #1237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 216 commits into from
Apr 23, 2025

Conversation

russellwheatley
Copy link
Member

@russellwheatley russellwheatley commented Feb 18, 2025

Work in progress

Copy link
Contributor

@morganchen12 morganchen12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good. Had one architecture question for consideration.

Copy link
Contributor

@morganchen12 morganchen12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything that's marked TODO can be done in a future PR.


public init() {}

private var limitedLoginBinding: Binding<Bool> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This computed property does a lot. It is trying to sync with ATTrackingManager.trackingAuthorizationStatus, and also drives showUserTrackingAlert and limitedLogin.

We should simplify this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is an alternative solution that feels cleaner:

  @State private var showUserTrackingAlert = false
  @State private var trackingAuthorizationStatus: ATTrackingManager.AuthorizationStatus = .notDetermined

  var isLimitedLogin: Bool {
    trackingAuthorizationStatus != .authorized
  }

  public init() {
    _trackingAuthorizationStatus = State(initialValue: ATTrackingManager.trackingAuthorizationStatus)
  }

  func requestTrackingPermission() {
    ATTrackingManager.requestTrackingAuthorization { status in
      Task { @MainActor in
        trackingAuthorizationStatus = status
        if status != .authorized {
          showUserTrackingAlert = true
        }
      }
    }
  }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated to reduce scope of binding: 0d5d8ba (#1237)

Not sure if you agree but a binding was still needed to stop toggle from switching if limited login wasn't possible.

func deleteUser() async throws {
do {
if let user = auth.currentUser, let lastSignInDate = user.metadata.lastSignInDate {
let needsReauth = !lastSignInDate.isWithinPast(minutes: 5)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of making assumptions about the grace period, it'd be better to make the call and handle the error.

See https://github.com/peterfriese/IdentityKit/blob/a9383206ef3dce073e3b64b6828ccb8d3b77315b/Sources/IdentityKit/Service/AccountService.swift#L68

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for that, that's a much cleaner approach so I have leaned heavily on it and will use that for reauthenticate operations for other providers. I have tweaked it slightly by keeping it swiftui and removing the password prompt via UIKit:

16131d6 (#1237)

Copy link
Contributor

@peterfriese peterfriese left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good. I left a few comments, happy for you do address them in a follow-up PR.

I'd also like to see the following:

  1. Previews for all views. At the moment, it's not possible to preview the views, which makes it difficult to judge the design.
  2. Package.swift files for the individual modules (to support (1))

Approved provided my remarks are addressed in follow-up PRs.

}
}

struct ContentView: View {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: please move the ContentView into a separate file to make it easier to find.

}.padding(.vertical, 6)
.background(Divider(), alignment: .bottom)
.padding(.bottom, 4)
Button(action: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO:
Nit: I would prefer the following signature (here, and in general):

    Button {
    } label: {
    }

} else {
Text(authService.authenticationFlow == .login ? "Login" : "Sign up")
VStack { Divider() }
EmailAuthView()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this means that we'll always have Email/Password be the most prominent provider. I would advocate to allow users to instantiate EmailAuthView themselves via the providerButtons closure.

  1. I think we should no longer promote Email/Password as the go-to auth provider. Passwords are inherently insecure, and we should promote more secure providers instead.
  2. This gives developers more flexibility (e.g. put SiwA / SiwG first, and Email last)

case user(String)
}

public class GoogleProviderSwift: @preconcurrency GoogleProviderProtocol {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super happy with the Swift suffix. Also, can we include Auth in the name? Same for the protocol(s).

This applies to all providers.

@russellwheatley russellwheatley marked this pull request as ready for review April 23, 2025 10:50
@russellwheatley
Copy link
Member Author

Thanks, @peterfriese. Now the last bits of feedback have been resolved, and as discussed in the last meeting, I will merge this PR. I'll follow up with the further suggestions you've made with the exception of email/password View update. This is on hold until we have finalised solution for using View modifiers (See this PR). But I think we're all in agreement, users should be able to decide if they want email/password auth which will be opted-in (i.e. something like AuthService().withEmailPasswordSignIn()).

@russellwheatley russellwheatley merged commit a29ab0a into main Apr 23, 2025
14 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants