2

I am getting deeplink URL from QRCODE scan but it is showing Web URL query is empty (implemented with firebase dynamic links). Associated domains set to "applinks:avrhub.page.link/Product".

"FirebaseDynamicLinksCustomDomains" in info.plist set to "https://avrhub.page.link" and "https://avrhub.page.link/Product"

enter image description here

Deeplink url:enter image description here

Code For Deeplinking:

func handleIncomingDynamicLink(_ dynamicLink:DynamicLink){
    
    
    
    guard let url = dynamicLink.url else {
            print("My Dynamic Link object has no url")
            return
        }
        print("Your Incoming link Parameter is \(url.absoluteString)")
        
        guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
        let queryItems = components.queryItems else {return}
        for queryItem in queryItems {
            
            Api.Params.inputProductId = Int(queryItem.value!)!
            print("Parameter \(queryItem.name) has a value of \(queryItem.value ?? "")")
        }
        
        Switcher.updateRootVC()
        Api.Params.isDeepLink = true

        if dynamicLink.matchType == .unique {
            print("The dynamic link is Unique")
        }
    }


func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
             
    if let incomingURL = userActivity.webpageURL {
        print("incoming URL is \(incomingURL)")
        let linkHandled = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { ( dynamicLink, error) in
            guard error == nil else {
                print("Found an error \(error!.localizedDescription)")
                return
            }
            if let dynamicLink = dynamicLink {
                self.handleIncomingDynamicLink(dynamicLink)
            }
            
        }
        if linkHandled {
  
            return true
        } else {
            return false
        }
    }
    
    return false
    
}


          
    func application(
        _ app: UIApplication,
        open url: URL,
        options: [UIApplication.OpenURLOptionsKey : Any] = [:]
    ) -> Bool {

        ApplicationDelegate.shared.application(
            app,
            open: url,
            sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
            annotation: options[UIApplication.OpenURLOptionsKey.annotation]
        )
        
        
        
        if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url){
            self.handleIncomingDynamicLink(dynamicLink)
            return true
        } else {
            return GIDSignIn.sharedInstance().handle(url)
        }


    }

Even analytics is not giving any error

enter image description here

13
  • 1
    Given it seems the app is opening when you tap on the universal link, seems that that piece is set up. Guessing it is something in terms of how the full universal link was composed. Was the link created in firebase console? Programatically? Commented Oct 6, 2020 at 8:05
  • 1
    are you able to see your link by debugging it in the browser? example.page.link/suffix?d=1 Commented Oct 6, 2020 at 8:06
  • 1
    Is the product ID the "30" in your example? Commented Oct 6, 2020 at 8:11
  • 1
    @HanzalaRaza product id is dynamic so you need to create dynamic link on the go. Create it programmatically by using Firebase's dynamic link SDK. Commented Oct 6, 2020 at 8:21
  • 1
    No - seems your BE dev didn't properly generate the dynamic link Commented Oct 6, 2020 at 8:34

3 Answers 3

2

As mentioned in the comments you cannot create a dynamic link with variable product id in the firebase console, instead you need to generate it on the go. You can also include additional parameters if needed which may help in analytics for example if you would like to know which user share the link and what its impact...

In my opinion it's better to add product id as query parameter in the link. Moreover it will also be helpful in case of multi parameters. You can parse it easily with the parameter name for example:

var productId: String?
let urlComponents = URLComponents(string: urlString)
if let queryItems = urlComponents?.queryItems {
    for queryItem in queryItems {
        if queryItem.name == "product_id" {
           productId = queryItem.value
        }
    }
}

Here is my code for generating dynamic link programmatically.

func generateAndShareDynamicLink(event: Event, controller: UIViewController, presentationCompletion: @escaping (() -> Void), dismissCompletion: @escaping (() -> Void) ) {
        
        let user = Utility.shared.getCurrentUser()!
        let ownReferralCode = user.ownReferralCode.value
        let offerShareUrlString = youAPILink + "?referral=" + ownReferralCode + "&event_id=" + event.id.value + "&shared_by=" + user.userId.value + "&shared_by_name=" + user.fullName.value
        
        let url = URL(string: offerShareUrlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!)!
        
        let iOSNavigationParams = DynamicLinkNavigationInfoParameters()
        iOSNavigationParams.isForcedRedirectEnabled = false
        
        let linkComponents = DynamicLinkComponents(link: url, domainURIPrefix: dynamicLinkGenaricDomain)!
        linkComponents.navigationInfoParameters = iOSNavigationParams
        linkComponents.iOSParameters = DynamicLinkIOSParameters(bundleID: bundleId)
        linkComponents.iOSParameters?.appStoreID = kAppStoreId
        linkComponents.iOSParameters?.customScheme = theBarCodeInviteScheme
        
        linkComponents.androidParameters = DynamicLinkAndroidParameters(packageName: androidPackageName)
        
        let descText = "\(user.fullName.value) has shared an event with you, check it out!"
        linkComponents.socialMetaTagParameters = DynamicLinkSocialMetaTagParameters()
        linkComponents.socialMetaTagParameters?.title = "App Name"
        linkComponents.socialMetaTagParameters?.descriptionText = descText
        linkComponents.socialMetaTagParameters?.imageURL = tbcLogoUrl
        
        linkComponents.otherPlatformParameters = DynamicLinkOtherPlatformParameters()
        linkComponents.otherPlatformParameters?.fallbackUrl = URL(string: barCodeDomainURLString)
        
        linkComponents.shorten { (shortUrl, warnings, error) in
            
            guard error == nil else {
                presentationCompletion()
                controller.showAlertController(title: "Share Event", msg: error!.localizedDescription)
                return
            }
            
            if let warnings = warnings {
                debugPrint("Dynamic link generation warnings: \(String(describing: warnings))")
            }
            
            let activityViewController = UIActivityViewController(activityItems: [descText, shortUrl!], applicationActivities: nil)
            activityViewController.popoverPresentationController?.sourceView = controller.view
            activityViewController.completionWithItemsHandler = { (activityType, completed:Bool, returnedItems:[Any]?, error: Error?) in
                dismissCompletion()
            }
            controller.present(activityViewController, animated: true, completion: {
                presentationCompletion()
            })
        }
        
    }
Sign up to request clarification or add additional context in comments.

2 Comments

this same thing is available on the multiple platforms, you can also generate it on your back end as well.
hi I am facing the same error please check the link below help me if you have a solution stackoverflow.com/q/67019905/11468227
2

I had the same issue in that I always gets nil value while trying to get the Firebase Dynamic link from below function

DynamicLinks.dynamicLinks().dynamicLink(:)

I found on useful post on Github that explains that we need to add the domain in .plist file which is used in the dynamic link.

This works for me, may be this will help someone.

You can add your domain in plist like below:

<key>FirebaseDynamicLinksCustomDomains</key>
    <array>
        <string><YOUR_DOMAIN_NAME></string>
    </array>

Make sure that you are specifying https:// or http:// in the domain name.

Note: if you wish to explore how to handle Firebase dynamic links for iOS 13 and higher version iOS. You can visit this answer.

1 Comment

hi I am facing the same error please check the link below help me if you have a solution stackoverflow.com/q/67019905/11468227
1

I agree with the other answer that the best way to solve this is to get the back end developer to use the Firebase Dynamic Links SDK to properly generate a dynamic link and embed in the QR code.

However, if you don't have control of that, then you can take the incoming link and parse it for the product ID that is embedded. In which case, you don't need to use some of the Dynamic link capabilities for example, you could instead do the below:

if let incomingURL = userActivity.webpageURL {
    print("incoming URL is \(incomingURL)")
    handleIncomingURL(incomingURL)
}

//quick and dirty parse - you could do something a bit more robust based on your circumstances

func handleIncomingURL(_ url:URL) {
    
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true), let host = components.host else {
        return
    }
    var pathComponents = components.path.components(separatedBy: "/")
    // the first component is empty
    pathComponents.removeFirst()
    
    if pathComponents[0] == "Product" && pathComponents[1] != nil {
        print("found productId: \(pathComponents[1])")
        //Action here: jump to the right page from here, now that you have a product ID to work with
    } else {
        print("invalid URL path for my use case....")
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.