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 Dynamic Links sometimes got error NSPOSIXErrorDomain Code=53 "Software caused connection abort" #2303

Closed
zesoat opened this issue Jan 23, 2019 · 18 comments
Assignees

Comments

@zesoat
Copy link

zesoat commented Jan 23, 2019

  • Xcode version: 10.1
  • Firebase SDK version: 5.14
  • Firebase Component: FirebaseDynamicLinks
  • Component version: 3.3.0
  • IOS 12

I created dynamic links from firebase console. Then I clicked that link to open my app.
Sometimes I got success, but sometimes I got error from DynamicLinks.dynamicLinks().handleUniversalLink
in AppDelegate

Error Domain=NSPOSIXErrorDomain Code=53 "Software caused connection abort" UserInfo={_kCFStreamErrorCodeKey=53, _kCFStreamErrorDomainKey=1}

Steps to reproduce:

  1. click dynamic link to open my app.
  2. switch back and click dynamic link again
  3. loop 1-2

Relevant Code:

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        if let incomingURL = userActivity.webpageURL {
            let handleLink = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL, completion: { (dynamicLink, error) in

                guard error == nil else {
                    debugPrint(error)
                }

                if let dynamicLink = dynamicLink {
                    self.handleIncomingDynamicLink(dynamicLink)
                } else {
                    // Check for errors
                }
            })
            return handleLink
        }
        return false
    }

I've read issue from react-native-firebase

And this issue was fixed in 5.2.1 yesterday(22/01/2019)

@google-oss-bot

This comment has been minimized.

@morganchen12
Copy link
Contributor

Looks like this is the core issue, which cannot be resolved directly but can be worked around as has been done in the react native repo here. @dmandar, what do you think is the best course of action here?

@bhadresh8141
Copy link

I am facing the same error. @zesoat Did you got any solution for the same?
I am facing this issue on :
Xcode 10.1
iOS 12.1 (iPhone 6)

@zesoat
Copy link
Author

zesoat commented Jan 30, 2019

@bhadresh8141
I added delay 50ms before handleUniversalLink and it worked.

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        usleep(50000)
        if let incomingURL = userActivity.webpageURL {
            let handleLink = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL, completion: { (dynamicLink, error) in

        ..........
}

@bhadresh8141
Copy link

@zesoat Thanks...it works after putting delay 👍

ko2ic added a commit to ko2ic/plugins that referenced this issue Feb 8, 2019
As in link there is a case of nil at completion of handleUniversalLink.
firebase/firebase-ios-sdk#2303

Also, even if make this correction,  cause an error, so fixed it to tell
it to the dart side.
ko2ic added a commit to ko2ic/plugins that referenced this issue Mar 25, 2019
As in link there is a case of nil at completion of handleUniversalLink.
firebase/firebase-ios-sdk#2303

Also, even if make this correction,  cause an error, so fixed it to tell
it to the dart side.
ko2ic added a commit to ko2ic/plugins that referenced this issue Mar 25, 2019
As in link there is a case of nil at completion of handleUniversalLink.
firebase/firebase-ios-sdk#2303

Also, even if make this correction,  cause an error, so fixed it to tell
it to the dart side.
@morganchen12
Copy link
Contributor

Looks like the radar mentioned in the AFNetworking issue above was resolved and this issue hasn't seen any new reports.

@adarhef
Copy link

adarhef commented Jul 15, 2019

@morganchen12 This is now happening to me, exactly as reported here.
Same link, it works once after tapping, second time doesn't, then works again, then doesn't... on and on.

@morganchen12
Copy link
Contributor

morganchen12 commented Jul 15, 2019

@adarhef can you share a project that reproduces this behavior? Dynamic links will make a network request to resolve short links, which on poor networks may be cancelled by the system ("Software caused connection abort) when the app sending the request is backgrounded. My suspicion is you can mitigate this error by creating a background task when handling the universal link and end the background task in the universal link's completion handler.

@morganchen12 morganchen12 reopened this Jul 15, 2019
@adarhef
Copy link

adarhef commented Jul 15, 2019

Unfortunately I cannot share a project reproducing this error. It is a short link, but my connection here can hardly be described as poor.
Sleeping (usleep(50000)) works around this issue for me as well.
Maybe it would be helpful to mention that the app is already opened, I go back and forth between the last two apps (mine and Mail) using the force touch gesture at the edge of the screen if you're familiar with it, sort of like swiping back in a navigation controller. Maybe this is causing weird backgrounding behavior.
Is it not possible for the framework to initiate the processing of the link in a background task? Or is it something the main applications has to do? It seems odd to me that clients should have to do that, unless you're truly just meaning this as a workaround.

Regardless I appreciate the quick reply!

@morganchen12
Copy link
Contributor

The network request cancellation is poorly documented, so it's not surprising that it's happening on any network quality. Does the error go away if you create a background task (as a workaround)?

@dmandar do you think automatically creating a background task is reasonable here?

@adarhef
Copy link

adarhef commented Jul 16, 2019

I just realized that in order to create a background task I need to add the Background Fetch capability. I've never done it and I'm not sure I want to just in order to work around this issue in my code.

I've tested simply wrapping the handle call in DispatchQueue.global(qos: .background).async { ... } and it also works. However, any other global QoS class like userInitiated and userInteractive doesn't work, so my workaround doesn't reliably work around this race condition. It seems that background just happens to be slow enough.
It also sucks because I can't use the return value of the handleUniversalLink and pass it as the return value for continue activity.

If only a background task is guaranteed to get around backgrounding-related issues without hacks in client code then it sounds like it's the only real solution to this issue. However I can see why adding the capability to the framework (if it's not there already) can be an issue in itself, in which case I'd consider adding one of the hacks suggested in this thread. I do feel like mine with a background QoS is much less offensive than sleeping.

@morganchen12
Copy link
Contributor

You shouldn't need any extra permissions to use this API.

@adarhef
Copy link

adarhef commented Jul 17, 2019

Okay, my bad. Wasn't aware of this one.
Unfortunately it didn't help in the way I used it:

    let id = application.beginBackgroundTask()
    
    return DynamicLinks.dynamicLinks().handleUniversalLink(url) { dynamiclink, error in
        // Here dynamiclink alternates between being nil and non-nil
        
        application.endBackgroundTask(id)
    }

Is this what you meant?

@morganchen12
Copy link
Contributor

Yep, that's exactly what I had in mind. Do you still get the same error? If so, then I'm most likely wrong about the cause of the issue.

Can you share an example project that reproduces this bug?

@adarhef
Copy link

adarhef commented Jul 18, 2019

Yes it's the same NSPOSIXErrorDomain Code=53 error.

I can't share an example project, but even if I could it wouldn't contain any more code than what I've already shared. I'm running on an iPhone 7 with iOS 12.3.1 and the latest framework version.

The use case is as I described earlier: Just go back and forth between Mail (where I tapped the short link). Turns out it doesn't matter how you do it: Force touch gesture, top left button to return to the last app, or even selecting the app manually from the app switcher.

@kenosan
Copy link

kenosan commented Jul 26, 2019

I was able to get around this using background tasks. So far, it seems to be working.


class AppDelegate: UIResponder, UIApplicationDelegate {
    /// Used to complete Firebase DynamicLink in background to avoid random error. (Reference: )
    fileprivate var backgroundTask: UIBackgroundTaskIdentifier = .invalid

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
            UIApplication.shared.endBackgroundTask(self!.backgroundTask)
            self?.backgroundTask = .invalid
        }

        let handled = DynamicLinks.dynamicLinks().handleUniversalLink(userActivity.webpageURL!) { (dynamiclink, error) in
            guard error == nil else {
                print("⛔️ problem handling Firebase DynamicLink: \(String(describing: error))")
                return
            }
            self.handeFirebaseUniversalLink(dynamiclink?.url)
        }

        return handled
    }
}

According to Apple's docs the UIApplication.shared.beginBackgroundTask handler is called shortly before the app’s remaining background time reaches 0. So as long as handleUniversalLink finishes before the time allocated to the background task, it should be good.

@rromanchuk
Copy link

I'm seeing handleUniversalLink always returning false with a custom domain (subdomain), it sounds very similar to https://stackoverflow.com/questions/50952035/firebase-dynamic-links-are-not-working-on-ios-when-the-dynamic-link-has-the-cust/51039418

I'm investigating and hunting where my configuration may have regressed but nothing obvious is revealing itself yet. Has anything recently changed with FirebaseDynamicLinksCustomDomains? I noticed in the docs you are specifying full paths, do i need to be using wild cards after the apex subdomain.example.com?

@morganchen12
Copy link
Contributor

Closing since this issue has staled.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants