attribution_linker 1.0.1
attribution_linker: ^1.0.1 copied to clipboard
A Flutter package for creating device fingerprints and linking attribution data using WebView. Collect comprehensive device information for analytics and attribution tracking.
Flutter Attribution Linker #
A Flutter package for creating device fingerprints and attribution linking using WebView. This package collects device and browser information to create a unique fingerprint for attribution tracking.
Features #
- π Device Fingerprinting: Collects comprehensive device and browser information
- π Headless WebView: Uses Flutter InAppWebView for data collection
- πΎ Caching: Fingerprint data is cached after first collection
- π Privacy-Aware: Collects only standard browser API data
- π± Cross-Platform: Works on iOS and Android
- π Post-FDL Solution: Enhanced attribution for App Links/Universal Links after Firebase Dynamic Links discontinuation
Installation #
Add this to your package's pubspec.yaml
file:
dependencies:
attribution_linker: ^0.0.1
Screenshot #

Example app showing device fingerprint collection in action
Usage #
Basic Usage #
import 'package:attribution_linker/attribution_linker.dart';
// Initialize the attribution linker
final linker = AttributionLinker();
linker.init();
// Collect fingerprint data
Map<String, dynamic> fingerprint = await linker.fingerprint;
print('Device OS: ${fingerprint['os_type']}');
print('Browser: ${fingerprint['browser_name']}');
print('Screen Resolution: ${fingerprint['screen_res']}');
Fingerprint Data Structure #
The fingerprint contains the following information:
os_type
: Operating system type (android, ios, macos, windows, linux, others)os_name
: Operating system nameos_version
: Operating system versionbrowser_name
: Browser namebrowser_version
: Browser versiondevice_model
: Device modeldevice_type
: Device typedevice_arch
: Device architecturedevice_bitness
: Device bitness (32/64 bit)screen_res
: Screen resolution (e.g., "1920x1080")pixel_ratio
: Device pixel ratiotimezone
: System timezonelanguage
: Browser languagecpu_cores
: Number of CPU coresdevice_memory
: Device memory in GBsystem_brightness
: System theme (light/dark)user_agent
: Full user agent string- And more...
Technical Implementation #
This package uses:
- flutter_inappwebview: For creating a headless WebView
- UAParser.js: For parsing user agent information
- Navigator APIs: For collecting device information
- Singleton Pattern: For efficient memory usage
Attribution Linking Architecture #
Overview #
This package implements a privacy-aware attribution linking system that connects web interactions to mobile app installations without relying on traditional tracking identifiers. The solution uses device fingerprinting to create a "trusted dimension" that serves as a matching key between web and mobile platforms.
Technical Flow #
sequenceDiagram
participant User
participant WebBrowser as Web Browser
participant BE as Backend Server
participant Cache as Redis/MongoDB
participant MobileApp as Mobile App
Note over User,MobileApp: 1. Web Interaction Phase
User->>WebBrowser: Clicks attribution link with parameters
Note over WebBrowser: https://example.com?utm_source=google&campaign_id=123
WebBrowser->>WebBrowser: Collect device fingerprint
Note over WebBrowser: os_type, screen_res, timezone, etc.
WebBrowser->>WebBrowser: Generate trusted_dimension
Note over WebBrowser: ip-macos-macos-1920x1080-2-asia/ho_chi_minh
WebBrowser->>BE: Send fingerprint + URL parameters
Note over WebBrowser,BE: POST /api/attribution
BE->>Cache: Store with 15-minute TTL
Note over Cache: Key: trusted_dimension<br/>Value: {utm_source, campaign_id, timestamp}
Note over User,MobileApp: 2. App Installation Phase
User->>MobileApp: Opens mobile app
MobileApp->>MobileApp: Collect device fingerprint
Note over MobileApp: Same fingerprinting logic
MobileApp->>MobileApp: Generate trusted_dimension
MobileApp->>BE: Request attribution data
Note over MobileApp,BE: POST /api/attribution/lookup
BE->>Cache: Query by trusted_dimension
Note over Cache: Find matches within 15 minutes
BE->>BE: Apply Cosine Similarity
Note over BE: Calculate similarity score<br/>for fuzzy matching
BE->>MobileApp: Return attribution data
Note over BE,MobileApp: {utm_source: "google", campaign_id: "123", confidence: 0.95}
MobileApp->>MobileApp: Process attribution
Note over MobileApp: Track install source<br/>without PII
Key Components #
1. Device Fingerprinting
- Web Side: JavaScript APIs collect browser and device information
- Mobile Side: Flutter package collects equivalent device information
- Consistency: Both platforms use identical fingerprinting logic
2. Trusted Dimension
A unique identifier created by combining:
ip
: User's IP addressos_type
: Operating system typeos_name
: Operating system namescreen_res
: Screen resolutionpixel_ratio
: Device pixel ratiotimezone
: System timezone
Format: ip-ostype-osname-screenres-pixelratio-timezone
Example: 192.168.1.1-macos-macos-1920x1080-2-asia/ho_chi_minh
3. Backend Storage
{
"trusted_dimension": "192.168.1.1-macos-macos-1920x1080-2-asia/ho_chi_minh",
"attribution_data": {
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "mobile_app",
"campaign_id": "123",
"click_id": "abc123"
},
"timestamp": "2024-01-15T10:30:00Z",
"ttl": 900
}
4. Matching Algorithm
- Exact Match: Direct trusted_dimension lookup
- Fuzzy Match: Cosine similarity for partial matches
- Time Window: Only consider records within 15 minutes
- Confidence Score: Return matching confidence level
Benefits #
- π Privacy-First: No personal identifiers or persistent tracking
- π― Accurate: High precision through device fingerprinting
- β‘ Fast: Redis caching for quick lookups
- π‘οΈ Secure: Short TTL prevents long-term tracking
- π Transparent: Clear confidence scores for attribution
Use Cases #
- App Install Attribution: Track which marketing campaigns drive app installs
- Cross-Platform Analytics: Connect web and mobile user journeys
- Campaign ROI: Measure effectiveness of web-to-app campaigns
- A/B Testing: Test different onboarding flows across platforms
Live Demo #
Try the web fingerprinting demo: https://hautvfami.github.io/attribution_linker/web_fingerprint.html
Comparison with Existing Solutions #
vs Branch.io & AppsFlyer #
Traditional attribution platforms like Branch.io and AppsFlyer use more complex multi-dimensional approaches:
-
β Their Advantages:
- Multiple tracking methods (IDFA, GAID, probabilistic matching)
- Advanced ML algorithms and cross-device tracking
- Comprehensive analytics and fraud detection
- Enterprise-grade infrastructure and support
-
β Our Advantages:
- Privacy-First: No reliance on advertising IDs or persistent tracking
- Cost-Effective: Free tier options with Cloudflare Workers + MongoDB
- Transparent: Open-source implementation you can audit and customize
- Lightweight: Simple fingerprinting without complex device graphs
When to Use This Solution #
This package is ideal when you need:
- Reasonable Accuracy: 70-85% attribution accuracy for most use cases
- Privacy Compliance: GDPR/CCPA compliant without complex consent flows
- Cost Control: Predictable costs with free tier options
- Simple Implementation: Quick setup without extensive SDK integration
For enterprise needs requiring 95%+ accuracy, consider traditional platforms.
Firebase Dynamic Links Alternative #
π¨ FDL Discontinuation Impact #
Firebase Dynamic Links (FDL) will be discontinued on August 25, 2025. This creates a significant gap for apps relying on FDL for attribution and deep linking. While App Links (Android) and Universal Links (iOS) provide deep linking functionality, they lack the attribution capabilities that FDL offered.
π Enhanced App Links/Universal Links #
This package provides the missing attribution layer for native deep links:
graph LR
A[Marketing Campaign] --> B[Landing Page]
B --> C{User Action}
C -->|Install App| D[App Store]
C -->|Open App| E[App Links/Universal Links]
D --> F[App First Launch]
E --> G[App Deep Link Handler]
F --> H[Attribution Linker]
G --> H
H --> I[Campaign Attribution]
subgraph "Attribution Flow"
J[Web Fingerprint] --> K[Trusted Dimension]
K --> L[Backend Storage]
M[App Fingerprint] --> N[Lookup & Match]
L --> N
N --> O[Attribution Result]
end
Implementation Strategy #
1. Landing Page Setup
<!-- Replace FDL with regular App Links -->
<script>
// Collect fingerprint when user lands
const fingerprint = await collectFingerprint();
const utmParams = getURLParameters();
// Store attribution data
await storeAttribution(fingerprint, utmParams);
// Redirect to App Link/Universal Link
if (isMobile()) {
window.location = 'https://yourapp.com/campaign?utm_source=google';
}
</script>
2. App Integration
// Replace FDL handling with Attribution Linker
class AppLinkHandler {
static Future<void> handleAppLink(String link) async {
// Get attribution data first
final linker = AttributionLinker();
final attribution = await linker.getAttributionData();
// Process deep link with attribution context
await processDeepLink(link, attribution);
}
}
Migration Benefits #
- β No Service Dependency: Unlike FDL, no Google service dependency
- β Cost Control: Predictable costs vs potential FDL pricing
- β Privacy Compliant: Built-in GDPR/CCPA compliance
- β Customizable: Full control over attribution logic
- β Performance: Faster than FDL redirects
FDL vs Attribution Linker Comparison #
Feature | Firebase Dynamic Links | Attribution Linker |
---|---|---|
Service Status | β Discontinued 08/25/2025 | β Active Development |
Attribution | β Built-in | β Enhanced with fingerprinting |
Deep Linking | β Automatic | β οΈ Requires App Links/Universal Links |
Privacy | β οΈ Google's terms | β Full privacy control |
Cost | β Paid service | β Free tier available |
Customization | β Limited | β Full source code access |
Cross-Platform | β iOS/Android | β iOS/Android/Web |
Recommended Infrastructure #
Free Tier Setup with Cloudflare + MongoDB #
graph TD
A[Web Browser] -->|Fingerprint + UTM| B[Cloudflare Worker]
C[Mobile App] -->|Fingerprint Request| B
B -->|Store/Query| D[MongoDB Atlas Free Tier]
B -->|Cache| E[Cloudflare KV Storage]
subgraph "Package-based Splitting"
F[com.example.app1] --> D1[MongoDB Collection 1]
G[com.example.app2] --> D2[MongoDB Collection 2]
H[com.example.app3] --> D3[MongoDB Collection 3]
end
Implementation Benefits #
- Cloudflare Workers: 100k requests/day free tier, global edge computing
- MongoDB Atlas: 512MB free tier, sufficient for attribution data
- Package Splitting: Separate collections per app bundle ID for better organization
- KV Storage: Cache frequent lookups for faster response times
Cost Optimization #
// Example Cloudflare Worker structure
export default {
async fetch(request) {
const url = new URL(request.url);
const bundleId = url.searchParams.get('bundle_id');
// Split data by package ID for better organization
const collection = `attribution_${bundleId.replace(/\./g, '_')}`;
// Use KV for caching frequent trusted_dimensions
const cached = await KV.get(trustedDimension);
if (cached) return new Response(cached);
// MongoDB query with 15-minute TTL
const result = await queryMongoDB(collection, trustedDimension);
// Cache result for 5 minutes
await KV.put(trustedDimension, JSON.stringify(result), {expirationTtl: 300});
return new Response(JSON.stringify(result));
}
}
Privacy Considerations #
This package only collects information that is freely available through standard web APIs. No personal information or unique identifiers are collected without explicit user consent.
The trusted dimension approach ensures:
- No PII Collection: Only technical device characteristics
- Short Data Retention: 15-minute TTL for attribution data
- Opt-out Friendly: Users can disable fingerprinting
- GDPR Compliant: Follows privacy-by-design principles
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is licensed under the MIT License - see the LICENSE file for details.