DavidWells / analytics

Lightweight analytics abstraction layer for tracking page views, custom events, & identifying visitors
https://getanalytics.io
MIT License
2.47k stars 245 forks source link

Use fingerprint as anonymousId? #171

Closed Fnxxxxo closed 3 years ago

Fnxxxxo commented 3 years ago

I want to integrate FingerprintJS with my browser specific plugin to use the fingerprint as anonymousId. But this require async bootstrap process. I want a feature to init plugin like:

const plugin = {
  name: 'async',
  bootstrap({ instance }) {
    Fingerprint2.load({ delayFallback: 500 }).then(agent => {
      agent.get({
        debug: process.env.NODE_ENV === 'development'
      }).then(({ components }) => {
        const fingerprint = Fingerprint2.hashComponents({
          ...components,
          ...domain
        })
        instance.setAnonymousId(fingerprint)
        // Something like async callback.
        instance.init()
      })
    })
  }
}
DavidWells commented 3 years ago

The anonId is set as value as soon as analytics loads.

You'd need to do something like this and use the (beta) initialUser config value

import Analytics from 'analytics'

let analytics

function loadAnalytics() {
  // Prompt for user opt it 😃

  // Then
  Fingerprint2.load({ delayFallback: 500 }).then(agent => {
    agent.get({
      debug: process.env.NODE_ENV === 'development'
    }).then(({ components }) => {
      const fingerprint = Fingerprint2.hashComponents({
        ...components,
        ...domain
      })
      analytics = Analytics({
         app: 'app-name',
         plugins: [
           // ... your analytics integrations
         ],
         initialUser: {
           anonymousId: fingerprint,
         },
       })
    })
  })
}

loadAnalytics()

export default analytics

I'd advise checking for user permissions before using any kind of fingerprinting. ❤️

Fnxxxxo commented 3 years ago

@DavidWells Thanks for your replay. The load function is async and this async module may result in unefined. Are there any way to insert the anonymousId but keep the analytics reference? I mean something like:

const analytics = Analytics({
    app: 'app-name',
    plugins: [
        // ... your analytics integrations
    ],
    async initialUser() {
        const anonymousId = await Fingerprint2.load({ delayFallback: 500 })
        return { anonymousId }
    }
})
export default analytics
Fnxxxxo commented 3 years ago

By the way, initialUser is not typed and complained in typescript.

Fnxxxxo commented 3 years ago

@DavidWells I find it hard to use initialUser since the given anonymousId is refreshed after analytics.reset(). Any way to keep using the initialUser or use a callback to pick a given ID?

DavidWells commented 3 years ago

I find it hard to use initialUser since the given anonymousId is refreshed after analytics.reset(). Any way to keep using the initialUser or use a callback to pick a given ID?

This is a good question. Calling analytics.reset is intended to completely remove visitor information and start with a fresh visitor. This is why it resets the anonymous ID

What kind of behavior are you looking for?

Fnxxxxo commented 3 years ago

@DavidWells I would like to use most of the original lib. Just replace the uuid with fingerprint. In some case, I need refresh the use context. Maybe I miss use the analytics.reset since I need to keep the visitor ID identifier. A analytics.clear method is better for me.