Home > Net >  How to set up Firebase Google SignIn 6.0.2 using SwiftUI 2.0 architecture?
How to set up Firebase Google SignIn 6.0.2 using SwiftUI 2.0 architecture?

Time:10-14

I'm trying to set up the latest GoogleSignIn with SwiftUI. Official Firebase documentation offers outdated approach designed for UIKit, ViewControllers and AppDelegate, so there is simply no way to find out what workaround is needed to make it work. I was able to implement UIApplicationDelegateAdaptor to get access to didFinishLaunchingWithOptions method to configure FirebaseApp and GIDSignIn. While following this documentation: https://firebase.google.com/docs/auth/ios/google-signin I ultimately stuck on the step 4. It's unclear where do I have to use this code or how to integrate it into SwiftUI paradigm:

guard let clientID = FirebaseApp.app()?.options.clientID else { return }

// Create Google Sign In configuration object.
let config = GIDConfiguration(clientID: clientID)

// Start the sign in flow!
GIDSignIn.sharedInstance.signIn(with: config, presenting: self) { [unowned self] user, error in

  if let error = error {
    // ...
    return
  }

  guard
    let authentication = user?.authentication,
    let idToken = authentication.idToken
  else {
    return
  }

  let credential = GoogleAuthProvider.credential(withIDToken: idToken,
                                                 accessToken: authentication.accessToken)

  // ...
}

I'm aware of this guide from Google: https://developers.google.com/identity/sign-in/ios/quick-migration-guide but there is no code example of how to do it properly.

CodePudding user response:

You would probably want to run that code as the result of an action the user takes. After pressing a Button, for example.

The tricky part is going to be that GIDSignIn.sharedInstance.signIn wants a UIViewController for its presenting argument, which isn't necessarily straightforward to get in SwiftUI. You can use a UIViewControllerRepresentable to get a reference to a view controller in the hierarchy that you can present from.

class LoginManager : ObservableObject {
    var viewController : UIViewController?
    
    func runLogin() {
        guard let viewController = viewController else {
            fatalError("No view controller")
        }
        
        //Other GIDSignIn code here. Use viewController for the `presenting` argument
    }
}

struct DummyViewController : UIViewControllerRepresentable {
    var loginManager : LoginManager
    
    func makeUIViewController(context: Context) -> some UIViewController {
        let vc = UIViewController()
        loginManager.viewController = vc
        return vc
    }
    
    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        
    }
}

struct ContentView : View {
    @StateObject private var loginManager = LoginManager()
    
    var body: some View {
        VStack(spacing: 0) {
            Button(action: {
                loginManager.runLogin()
            }) {
                Text("Login")
                DummyViewController(loginManager: loginManager)
                    .frame(width: 0, height: 0)
            }
        }
    }
}
  • Related