iosswiftfirebase-dynamic-links

How to create Firebase Dynamic Link manually with multiple query parameters?


This is my custom parameters path to add for dynamic link:

let parameters = "action=ORDER&codeId=1&goId=2"

This is how I create manual Dynamic Link:

let domain = "joytst.page.link"
let string = "https://\(domain)/?link=https://\(domain)/?\(parameters)"

and the output for shorten URL is:

"https://joytst.page.link/syjd9GjRH3SYCXFH7"

Then I am trying to create long url back from just shortened, and I got:

"https://joytst.page.link/?action=ORDER"

Where are codeId=1&goId=2 parameters?


Solution

  • You currently have:

    https://joytst.page.link/?link=https://joytst.page.link/?action=ORDER&codeId=1&goId=2
    

    So let's decompose it with params and rename base1 and base2 the two joytst.page.link parts, else it's hard to separate them.

    How it's really interpreted:

    https://base1/?
                   link=https://base2/?
                                       action=ORDER
                  &codeId=1
                  &goId=2
    

    How you think it's interpreted:

    https://base1/?
                   link=https://base2/?
                                       action=ORDER
                                      &codeId=1
                                      &goId=2
    

    You see that we can't guess what's the good interpretation from there, hence the rules and how it's done. The first one is the good interpretation of the URL and parameters.

    In reality:
    codeId=1 and goId=2 are params of base1 and action=ORDER is params of base2, that's why you get only action=ORDER because it doesn't know that codeId & goId are for link value.

    You need to fully percent escape linkValue, that way it will have codeId and goId.

    Your final url before shortening should be

    https://joytst.page.link/?link=https://joytst.page.link/?action%3DORDER%26codeId%3D1%26goId%3D2
    

    To illustrate it with your code:

    let parameters = "action=ORDER&codeId=1&goId=2"
    let domain = "joytst.page.link"
    let string = "https://\(domain)/?link=https://\(domain)/?\(parameters)"
    
    let components = URLComponents(string: string)
    print(components!.url!.absoluteString)
    components?.queryItems?.forEach({ print("\($0.name) : \($0.value)") })
    

    Output:

    $>https://joytst.page.link/?link=https://joytst.page.link/?action=ORDER&codeId=1&goId=2
    $>link : Optional("https://joytst.page.link/?action=ORDER")
    $>codeId : Optional("1")
    $>goId : Optional("2")
    

    Quick sample code with correctly percent escaping the full link value:

    func constructURL(baseURL: String, with params: [URLQueryItem]) -> URL? {
        var components = URLComponents(string: baseURL)
        if !params.isEmpty {
            components?.queryItems = params
        }
        return components?.url
    }
    
    
    
    let domain = "joytst.page.link"
    let embededQueryItems = [URLQueryItem(name: "action", value: "ORDER"),
                             URLQueryItem(name: "codeId", value: "1"),
                             URLQueryItem(name: "goId", value: "2")
    ]
    let linkValue = constructURL(baseURL: "https://\(domain)/", with: embededQueryItems)
    
    let finalURL = constructURL(baseURL: "https://\(domain)/", with: [URLQueryItem(name: "link", value: linkValue!.absoluteString)])
    print(finalURL!.absoluteString)
    
    
    let components = URLComponents(string: finalURL!.absoluteString)
    print(components!.url!.absoluteString)
    components?.queryItems?.forEach { 
        print("\($0.name) : \($0.value)")
    }
    

    Output:

    $>https://joytst.page.link/?link=https://joytst.page.link/?action%3DORDER%26codeId%3D1%26goId%3D2
    $>link : Optional("https://joytst.page.link/?action=ORDER&codeId=1&goId=2")