Skip to content
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

Firebase passwordless auth deeplinks aren't working #33

Open
0xymoro opened this issue Jul 30, 2023 · 1 comment
Open

Firebase passwordless auth deeplinks aren't working #33

0xymoro opened this issue Jul 30, 2023 · 1 comment

Comments

@0xymoro
Copy link

0xymoro commented Jul 30, 2023

Spent days on this - really not sure what's wrong...

iOS is able to open deeplinks, and this code in appdelegate is able to see them come in:

`   func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
            // Log the dynamic link or handle the deep link.
            print("Dynamic link detected: \(dynamicLink)")
            return true
        }
        return false
    }`

What I did in a pretty entry point authentication handler:

import { FirebaseDynamicLinks } from '@pantrist/capacitor-firebase-dynamic-links';
...
FirebaseDynamicLinks.addListener('deepLinkOpen', async (data: { url: string }) => {

The links themselves are passwordless authenticator links in the format:
https://domain.page.link/?link=https://domain.com/__/auth/action?apiKey%3Dcode%26mode%3DsignIn%26oobCode%3Dcode%26continueUrl%3Dhttps://domain.com/%26lang%3Den&apn=com.domain.app&amv&ibi=com.domain.app&ifl=https://domain.com/__/auth/action?apiKey%string%26mode%3DsignIn%26oobCode%code%26continueUrl%3Dhttps://domain.com/%26lang%3Den

and are created by:

sendSignInLinkToEmail(FIREBASE_AUTH, email, {
        url: https://domain.com,
        handleCodeInApp: true,
        iOS: {
          bundleId: 'com.domain.app'
        },
        android: {
          packageName: 'com.domain.app',
          installApp: true,
          minimumVersion: '0'
        },
        dynamicLinkDomain: 'domain.page.link'
      });

I even made this plugin update to log where it's failing, but none of this runs.

`    @objc func handleUrlOpened(notification: NSNotification) {
        if let object = notification.object as? [String: Any?] {
            if let url = object["url"] as? URL {
                if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
                    print("Handling dynamic link 1")
                    self.handleLink(dynamicLink)
                } else {
                    print("Some other link case do nothing...")
                    // This is likely to be a custom URL from some other process
                }
            } else {
                print("CapacitorFirebaseDynamicLinks.handleUrlOpened() - url is not of type URL")
            }
        } else {
            print("CapacitorFirebaseDynamicLinks.handleUrlOpened() - object is not of type [String: Any?]")
        }
    }

    @objc func handleUniversalLink(notification: NSNotification) {
        if let object = notification.object as? [String: Any?] {
            if let url = object["url"] as? NSURL {
                if let parsed = URL(string: url.absoluteString!) {
                    let response = DynamicLinks.dynamicLinks().handleUniversalLink(parsed) { (dynamiclink, error) in
                        if let error = error {
                            print("handleUniversalLink -> error: \(String(describing: error.localizedDescription))")
                        } else if let dynamicLink = dynamiclink {
                            print("In universal link 1")
                            self.handleLink(dynamicLink)
                        }
                    }
                    if !response {
                        print("""
                        CapacitorFirebaseDynamicLinks.handleUniversalLink()
                        Unable to parse dynamic link. Please ensure you have set up Firebase Dynamic Links correctly.
                        """)
                    }
                } else {
                    print("CapacitorFirebaseDynamicLinks.handleUniversalLink() - Unable to parse URL")
                }
            } else {
                print("CapacitorFirebaseDynamicLinks.handleUniversalLink() - url is not of type NSURL")
            }
        } else {
            print("CapacitorFirebaseDynamicLinks.handleUniversalLink() - object is not of type [String: Any?]")
        }
    }

    func handleLink(_ dynamicLink: DynamicLink) {
        if let url = dynamicLink.url {
            print("CapacitorFirebaseDynamicLinks.handleLink() - url: \(url.absoluteString)")
            self.notifyListeners("deepLinkOpen", data: ["url": url.absoluteString], retainUntilConsumed: true)
        } else {
            print("CapacitorFirebaseDynamicLinks.handleLink() - Dynamic link has no url")
        }
    }`
@0xymoro
Copy link
Author

0xymoro commented Jul 30, 2023

Ok - so had to change native code as to which notification it sent and conform with the plugin's expected notification type/name. This seems quite undocumented and a little over the top so I think I'm hacking around something obvious but don't know what it is, but this hack works well.

Code that worked:

` @available(iOS 9.0, *)
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
let handledByApplicationDelegateProxy = ApplicationDelegateProxy.shared.application(app, open: url, options: options)
let sourceApplication = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String
let handledByCustomLogic = application(app, open: url, sourceApplication: sourceApplication, annotation: "")

    return handledByApplicationDelegateProxy || handledByCustomLogic
}

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
        // Log the dynamic link or handle the deep link.
        print("Dynamic link detected: \(dynamicLink)")
        
        // Post a notification with the dynamic link
        NotificationCenter.default.post(name: Notification.Name.capacitorOpenURL, object: ["url": url])
        
        return true
    }
    return false
}

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    let handledByDynamicLinks = DynamicLinks.dynamicLinks().handleUniversalLink(userActivity.webpageURL!) { dynamiclink, error in
        if let error = error {
            print("Failed to handle universal link: \(error)")
        } else if let dynamiclink = dynamiclink {
            // Log the dynamic link or handle the deep link.
            print("Dynamic link detected: \(dynamiclink)")
            
            // Post a notification with the dynamic link
            NotificationCenter.default.post(name: Notification.Name.capacitorOpenUniversalLink, object: ["url": userActivity.webpageURL!])
        }
    }

    return handledByDynamicLinks || ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
}`

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

No branches or pull requests

1 participant