'Firebase AuthUI not triggering callback function with Swift
I recently updated an app I'm working on to IOS15 and I've hit a snag while testing.
When the user tries to log into the app using FirebaseUI (with google or email) the login process completes but does not trigger the callback function didSignInWith: from the delegate.
None of the print statements are being called from this class, but if I restart the app it behaves as if login was successful
Does anybody know what I've done wrong here?... as far as I can tell everything should work fine
import UIKit
import UserNotifications
import FirebaseUI
class LoginViewCell: UICollectionViewCell, FUIAuthDelegate {
let imageView: UIImageView
let title: UILabel
let text: UILabel
var parent: WelcomeViewController? = nil
var authUI: FUIAuth
override init(frame: CGRect) {
authUI = FUIAuth.defaultAuthUI()!
super.init(frame: frame)
let providers: [FUIAuthProvider] = [FUIGoogleAuth(authUI: authUI), FUIEmailAuth()
]
authUI.providers = providers
authUI.delegate = self
let loginButton = UIButton(frame: CGRect(x: 100, y: 100, width: 300, height: 50))
loginButton.backgroundColor = .blue
loginButton.setTitle("Let's Get Started!", for: .normal)
loginButton.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
loginButton.center = CGPoint(x: frame.width / 2, y: ((frame.height/4) * 3) + 50)
addSubview(loginButton)
}
@objc func buttonAction(sender: UIButton!) {
let authViewController = authUI.authViewController()
parent?.present(authViewController , animated: true, completion: nil)
}
//MARK: Authentication Delegate
func authUI(_ authUI: FUIAuth, didSignInWith user: User?, error: Error?) {
// handle user and error as necessary
print("Login attempted")
if( error != nil){
print("Error Logging In \(String(describing: error))")
}else{
userHandler.doesUserExist({(exists: Bool) in
if(exists){
self.parent?.dismiss(animated: true, completion: nil)
}else{
let manager = UserManagerViewController()
manager.shouldCreateUser = true
let nvc = CalendarNavigationController(rootViewController: manager)
self.parent?.present(nvc, animated: true, completion: nil)
}
})
}
}
func application(_ app: UIApplication, open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
let sourceApplication = options[UIApplication.OpenURLOptionsKey.sourceApplication] as! String?
if FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication) ?? false {
print("Think did log in successful")
return true
}
// other URL handling goes here.
print("think did not log in")
return false
}
}
Solution 1:[1]
Is your cell still displayed when the callback should get called ? If not then here's the problem :
Your cell object can be deallocated (managed by the UICollectionView), and it happens that it's also the delegate for firebase. When that happens, firebase call a delegate that is nil, and it does nothing.
What you can do is create a specific class that will conform to the delegate protocol, keep a strong reference to it in a controller or viewModel that won't be terminated unless you want it (here the controller of viewModel is the object that initialize the cell), pass it as a dependency to the cell object (dependency injection), and set it as the authUI.delegate. If you follow these instructions the delegate will be retained cause it has a strong reference.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Damien Bannerot |
