Firebase-ios-sdk: Firebase Dynamic Links sometimes got error NSPOSIXErrorDomain Code=53 "Software caused connection abort"

Created on 23 Jan 2019  路  18Comments  路  Source: firebase/firebase-ios-sdk

  • 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)

dynamiclinks

Most helpful comment

@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

        ..........
}

All 18 comments

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

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?

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)

@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

        ..........
}

@zesoat Thanks...it works after putting delay 馃憤

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

@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.

@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.

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!

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?

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.

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

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?

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?

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.

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鈥檚 remaining background time reaches 0. So as long as handleUniversalLink finishes before the time allocated to the background task, it should be good.

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?

Closing since this issue has staled.

Was this page helpful?
0 / 5 - 0 ratings