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

WebView approach not working #6

Closed
makma opened this issue Aug 17, 2021 · 2 comments · Fixed by #7
Closed

WebView approach not working #6

makma opened this issue Aug 17, 2021 · 2 comments · Fixed by #7
Assignees

Comments

@makma
Copy link
Member

makma commented Aug 17, 2021

Whem I follow the guidelines for the webview approach, vendorId tag is not reflected.

Steps to reproduce:

  1. Create view in swiftUI:
import SwiftUI
import WebKit
 
struct ContentView: View {
    var body: some View {
        Webview(url: URL(string: "https://eager-hermann-4ea017.netlify.app")!)
    }
}
 
struct Webview: UIViewRepresentable {
    let url: URL
 
    func makeUIView(context: UIViewRepresentableContext<Webview>) -> WKWebView {
        let webview = WKWebView()
 
        let vendorId = UIDevice.current.identifierForVendor?.uuidString ?? "undefined"

        let script = WKUserScript(source: "window.fingerprintjs.vendorId = \(vendorId)", injectionTime: .atDocumentStart, forMainFrameOnly: false)
 
        webview.configuration.userContentController.addUserScript(script)
 
        let request = URLRequest(url: self.url, cachePolicy: .returnCacheDataElseLoad)
        webview.load(request)
 
        return webview
    }
 
    func updateUIView(_ webview: WKWebView, context: UIViewRepresentableContext<Webview>) {
        let request = URLRequest(url: self.url, cachePolicy: .returnCacheDataElseLoad)
        webview.load(request)
    }
}
  1. Create hmlt page with FPJS on the URL specified in the Webview(url: URL(string: "https://eager-hermann-4ea017.netlify.app")!)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="description" content="Webpage description goes here" />
    <meta charset="utf-8" />
    <title>Change_me</title>
  </head>
  <body>
    <div class="container"></div>
    <script>
      const vendorId =
        window.fingerprintjs && window.fingerprintjs.vendorId
          ? window.fingerprintjs.vendorId
          : 'not-in-ios-context'

      function initFingerprintJS() {
        // Initialize an agent at application startup.
        const fpPromise = FingerprintJS.load({
          token: 'tQUwQQOuG9TNwqc6F4I2',
          region: 'eu',
          endpoint: 'https://fp.martinmakarsky.com',
        })

        // Get the visitor identifier when you need it.
        fpPromise
          .then((fp) =>
            fp.get({
              tag: {
                deviceId: vendorId,
                deviceType: 'ios',
              },
              linkedId: 'makma',
              extendedResult: true,
            })
          )
          .then((result) => {
            console.log(result.visitorId);
            var el = document.createElement("h1");
            el.innerText = result.visitorId;
            document.body.appendChild(el);
          })
      }
    </script>
    <script
      async
      src="https://cdn.jsdelivr.net/npm/@fingerprintjs/fingerprintjs-pro@3/dist/fp.min.js"
      onload="initFingerprintJS()"
    ></script>
  </body>
</html>
  1. Run iOS app, get visitorId and check tag on server API
    Expected output:
...
            "linkedId": "makma",
            "timestamp": 1629209018949,
            "time": "2021-08-17T14:03:38Z",
            "url": "https://eager-hermann-4ea017.netlify.app/",
            "tag": {
                "deviceId": "vendor-id-from-ios-context",
                "deviceType": "ios"
            }
...

Actual output:

...
            "linkedId": "makma",
            "timestamp": 1629209018949,
            "time": "2021-08-17T14:03:38Z",
            "url": "https://eager-hermann-4ea017.netlify.app/",
            "tag": {
                "deviceId": "not-in-ios-context",
                "deviceType": "ios"
            }
...

Note: I've also tried to set window object after webview.load(request)

Questions and suggestions:

  • is webview approach documented well?
  • is swift UI somehow specific?
  • should it be window.fingerprintjs.vendorId or window.FingerprintJS.vendorId?
  • I'd like to see full webview example in readme e.g. for SwiftUI
@pvels
Copy link
Contributor

pvels commented Aug 17, 2021

@makma
Yep, its documentation issue

This is happen because the fingerprintjs object undefined, as well as vendorId string must be escaped

Here is right solution:

let vendorId = UIDevice.current.identifierForVendor.flatMap { "'\($0.uuidString)'" } ?? "undefined"

WKUserScript(source: "window.fingerprintjs = { 'vendorId' : \(vendorId) }",
             injectionTime: .atDocumentStart,
             forMainFrameOnly: false)

@spalt08
can you please suggest better solution for script source and keypath?
And also maybe fingerprintjs object should be avoided as unnecessary?

@makma
Copy link
Member Author

makma commented Aug 17, 2021

Yep, @spalt08 has already written to me, I've checked this solution and it really works, gonna update readme with full swiftUI example in a minute, thx

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

Successfully merging a pull request may close this issue.

3 participants