Search code examples
iosswiftdeep-linkingfirebase-dynamic-linksios-universal-links

Dynamic link web URL query item is empty in Swift iOS


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


Solution

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