'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