swiftfirebasefirebase-authenticationswiftui

SwiftUI swizzling disabled by default, phone auth not working


I am building a screen with phone number login. I checked over and over again and the project is newly created, however, I am getting this log:

7.2.0 - [Firebase/Auth][I-AUT000015] The UIApplicationDelegate must handle remote notification for phone number authentication to work. If app delegate swizzling is disabled, remote notifications received by UIApplicationDelegate need to be forwarded to FIRAuth's canHandleNotificaton: method.

I did read in the documentation about swizzling and I don't know why it seems to be disabled, I did not disabled it. I have added GoogleServices-Info.plist into the app, I added in firebase panel the app apn auth key.

My entry point in the app looks like this:

@main
struct partidulverdeApp: App {
    
    init() {
        FirebaseApp.configure()
    }
    
    var body: some Scene {
        WindowGroup {
            MainView()
                .onOpenURL { url in
                    Auth.auth().canHandle(url.absoluteURL)
                }
        }
    }
}

My URL Types property has an entry with the RESERVED_CLIENT_ID

I am very desperate about this problem. Any idea is highly appreciated.

Edit1:

I did read the documentation and tried to handle notification with swizzling disabled, but I get the same error:

class AppDelegate: NSObject, UIApplicationDelegate {
    
    func application(_ application: UIApplication,
        didReceiveRemoteNotification notification: [AnyHashable : Any],
        fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
      if Auth.auth().canHandleNotification(notification) {
        completionHandler(.noData)
        return
      }
      
    }
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        print("Your code here")
        return true
    }
}

@main
struct partidulverdeApp: App {
    
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    init() {
        FirebaseApp.configure()
    }
    
    var body: some Scene {
        WindowGroup {
            MainView()
                .onOpenURL { url in
                    Auth.auth().canHandle(url.absoluteURL)
                }
        }
    }
}

Solution

  • Here's how to implement Phone Number Auth using the new SwiftUI 2 life cycle:

    1. Create a Firebase project and set up PhoneNumber Auth

    2. Add your iOS app to the Firebase project, download and add GoogleService-Info.plist to your project

    3. In Xcode, select the application target and enable the following capabilities:

      • Push notifications
      • Background modes > Remote notifications
    4. Create and register an APNS authentication key on the Apple developer portal

    5. Upload the key to Firebase (under Project Settings > Cloud messaging in the Firebase Console)

    6. Add the Firebase project's reversed client ID to your app's URL schemes

    7. In your Info.plist, set FirebaseAppDelegateProxyEnabled to NO

    8. Implement the AppDelegate as follows:

    class AppDelegate: NSObject, UIApplicationDelegate {
      func application(_ application: UIApplication,
                       didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()
        print("SwiftUI_2_Lifecycle_PhoneNumber_AuthApp application is starting up. ApplicationDelegate didFinishLaunchingWithOptions.")
        return true
      }
    
      func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        print("\(#function)")
        Auth.auth().setAPNSToken(deviceToken, type: .sandbox)
      }
      
      func application(_ application: UIApplication, didReceiveRemoteNotification notification: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("\(#function)")
        if Auth.auth().canHandleNotification(notification) {
          completionHandler(.noData)
          return
        }
      }
      
      func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
        print("\(#function)")
        if Auth.auth().canHandle(url) {
          return true
        }
        return false
      }
    }
    
    @main
    struct SwiftUI_2_Lifecycle_PhoneNumber_AuthApp: App {
      @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
      
      var body: some Scene {
        WindowGroup {
          ContentView()
            .onOpenURL { url in
              print("Received URL: \(url)")
              Auth.auth().canHandle(url) // <- just for information purposes
            }
        }
      }
    }
    
    

    For further reading, I suggest these two articles I wrote: