Skip to main content

Referral & Deep linking

 

Plugins : 

app_links:

android_play_install_referrer:


Link to share : 

https://yourweb.com/referral?code=TEST123

https://play.google.com/store/apps/details?id=com.erer&referrer=referral_code%3DTEST123


Manifest : 

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data
        android:host="yourweb.co"
        android:pathPrefix="/referral"
        android:scheme="https" />
</intent-filter>

Flutter Code : 

import 'package:app_links/app_links.dart';
import 'package:android_play_install_referrer/android_play_install_referrer.dart';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';

class DeepLinkService {
  static const String _referralKey = 'referral_code';
  static final AppLinks _appLinks = AppLinks();

  static Future<void> initDeepLinks() async {
    debugPrint('Initializing deep links...');

    // 1️⃣ Handle real-time deep/link stream
    try {
      final Uri? initialUri = await _appLinks.getInitialAppLink();
      if (initialUri != null) {
        debugPrint('Initial deep link: $initialUri');
        _processDeepLink(initialUri);
      }
    } catch (e) {
      debugPrint('Error getting initial deep link: $e');
    }

    _appLinks.uriLinkStream.listen((Uri? uri) {
      if (uri != null) {
        debugPrint('Stream deep link: $uri');
        _processDeepLink(uri);
      }
    });

    // 2️⃣ Handle deferred deep link (after installation)
    await _checkInstallReferrer();
  }

  static void _processDeepLink(Uri uri) {
    debugPrint('Processing deep link: $uri');
    if (uri.host == 'bike9pro.in' && uri.path.startsWith('/referral')) {
      final referralCode = uri.queryParameters['code'];
      if (referralCode != null) {
        debugPrint('Saving referral from deep link: $referralCode');
        _saveReferralCode(referralCode);
      }
    }
  }

  static Future<void> _checkInstallReferrer() async {
    if (defaultTargetPlatform == TargetPlatform.android) {
      try {
        final details = await AndroidPlayInstallReferrer.installReferrer;
        final raw = details.installReferrer; // e.g. "referral_code=TEST123"
        debugPrint('Install referrer raw: $raw');
        final Map<String, String> params = Uri.splitQueryString(raw!);
        final code = params['referral_code'];
        if (code != null) {
          debugPrint('Saving deferred referral: $code');
          _saveReferralCode(code);
        }
      } catch (e) {
        debugPrint('Failed to get install referrer: $e');
      }
    }
  }

  static Future<void> _saveReferralCode(String code) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_referralKey, code);
  }

  static Future<String?> getReferralCode() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(_referralKey);
  }

  static Future<void> clearReferralCode() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(_referralKey);
  }
}

main.dart 

await DeepLinkService.initDeepLinks();


Files on web for deeplink :

https://yourweb.com/.well-known/assetlinks.json


[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.app",
    "sha256_cert_fingerprints": [""]
  }
}]


Response In log for referral

I/flutter (17407): Initializing deep links...
W/FlutterJNI(17407): FlutterJNI.loadLibrary called more than once
W/FlutterJNI(17407): FlutterJNI.prefetchDefaultFontManager called more than once
W/FlutterJNI(17407): FlutterJNI.init called more than once
I/flutter (17407): Install referrer raw: referral_code=TEST123

I/flutter (17407): Saving deferred referral: TEST123 


 


Comments

Popular posts from this blog

Vibe Coding Tools List

  Vibe Coding Tools List Dedicated Vibe Coding Platforms: Google AI Studio / Firebase Studio:  Rapid full-stack application generation and deployment from conversational prompts. Replit Agent:  Cloud-based IDE with "Ghostwriter" AI for instant code generation, debugging, and deployment. Bolt:  Browser-based AI development agent for building full-stack web and mobile apps with natural language. Lovable:  Rapid UI prototyping tool that converts text commands into styled layouts with one-click export/deployment. v0 by Vercel:  Prompt-powered UI builder for generating production-ready React components with Tailwind CSS. Wegic:  Converts visual ideas or Figma designs into working code with prompt-based structure creation. AI-Powered IDEs and Code Editors: Cursor :  An "AI-first" code editor (based on VS Code) offering deep project awareness and multi-file conversational edits. Windsurf (formerly Codeium) :  Agentic AI-native IDE featuring the "Cas...

API security best practices

 API with a focus on security best practices : Key Security Practices Included: Input Validation and Sanitization : All inputs are validated and sanitized to prevent SQL injection and other attacks. Prepared Statements : All database queries use prepared statements to avoid SQL injection. Password Hashing : Passwords are hashed using password_hash() and verified using password_verify() . Token-Based Authentication : JSON Web Tokens (JWTs) are used for secure API authentication. Error Hiding : Error details are logged but not exposed to users in production. Strict Content-Type Header : Ensures only JSON payloads are processed. Rate Limiting and Throttling : Optional mechanisms to prevent abuse. Validation for IDs : Integer inputs (like user_id or exam_id ) are explicitly validated.