theprivacylabs_consent 0.2.1 copy "theprivacylabs_consent: ^0.2.1" to clipboard
theprivacylabs_consent: ^0.2.1 copied to clipboard

DPDP-compliant consent management SDK for Flutter apps. Manage user privacy preferences across iOS and Android.

Privacy Labs Flutter Consent SDK #

DPDP-compliant consent management SDK for Flutter apps.

Installation #

Add to your pubspec.yaml:

dependencies:
  theprivacylabs_consent: ^0.1.1

Then run:

flutter pub get

Quick Start #

1. Initialize the SDK #

import 'package:theprivacylabs_consent/theprivacylabs_consent.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  await PrivacyLabsConsent.init(ConsentConfig(
    orgId: 'your-org-id', // From Privacy Labs dashboard
    onConsentChange: (consent) {
      print('Consent changed: ${consent.preferences.toJson()}');
      
      // Enable/disable analytics based on consent
      if (consent.preferences.analytics) {
        Analytics.enable();
      } else {
        Analytics.disable();
      }
    },
    onError: (error) {
      print('Consent error: $error');
    },
    debug: kDebugMode, // Enable debug logs in development
  ));
  
  runApp(MyApp());
}

2. Create Privacy Settings Screen #

import 'package:flutter/material.dart';
import 'package:theprivacylabs_consent/theprivacylabs_consent.dart';

class PrivacySettingsScreen extends StatefulWidget {
  @override
  _PrivacySettingsScreenState createState() => _PrivacySettingsScreenState();
}

class _PrivacySettingsScreenState extends State<PrivacySettingsScreen> {
  List<ConsentCategory> _categories = [];
  ConsentState? _consent;
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _loadData();
  }

  Future<void> _loadData() async {
    final categories = await PrivacyLabsConsent.getCategories(lang: 'en');
    final consent = await PrivacyLabsConsent.getConsentStatus();
    
    setState(() {
      _categories = categories;
      _consent = consent;
      _isLoading = false;
    });
  }

  Future<void> _updateConsent(String categoryId, bool value) async {
    final current = _consent?.preferences ?? ConsentPreferences();
    
    ConsentPreferences updated;
    switch (categoryId) {
      case 'analytics':
        updated = current.copyWith(analytics: value);
        break;
      case 'marketing':
        updated = current.copyWith(marketing: value);
        break;
      case 'performance':
        updated = current.copyWith(performance: value);
        break;
      default:
        return;
    }
    
    await PrivacyLabsConsent.setConsent(updated);
    await _loadData(); // Refresh state
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading) {
      return Scaffold(
        appBar: AppBar(title: Text('Privacy Settings')),
        body: Center(child: CircularProgressIndicator()),
      );
    }

    return Scaffold(
      appBar: AppBar(title: Text('Privacy Settings')),
      body: ListView(
        padding: EdgeInsets.all(16),
        children: [
          Text(
            'Control how we use your data',
            style: Theme.of(context).textTheme.bodyLarge,
          ),
          SizedBox(height: 24),
          
          // Category toggles
          ..._categories.map((category) => Card(
            child: SwitchListTile(
              title: Text(category.name),
              subtitle: Text(category.description),
              value: _getCategoryValue(category.id),
              onChanged: category.required
                  ? null
                  : (value) => _updateConsent(category.id, value),
            ),
          )),
          
          SizedBox(height: 24),
          
          // Accept All button
          ElevatedButton(
            onPressed: () async {
              await PrivacyLabsConsent.acceptAll();
              await _loadData();
            },
            child: Text('Accept All'),
          ),
          
        ],
      ),
    );
  }

  bool _getCategoryValue(String categoryId) {
    if (_consent == null) return false;
    
    switch (categoryId) {
      case 'essential':
        return true;
      case 'analytics':
        return _consent!.preferences.analytics;
      case 'marketing':
        return _consent!.preferences.marketing;
      case 'performance':
        return _consent!.preferences.performance;
      default:
        return false;
    }
  }
}
// After user logs in
Future<void> handleLogin(String email, String password) async {
  final user = await authService.login(email, password);
  
  // Link consent to user identity for cross-device sync
  await PrivacyLabsConsent.linkIdentity(
    email,
    method: IdentityLinkMethod.login,
  );
}

// After user signs up
Future<void> handleSignup(String email, String password) async {
  final user = await authService.signup(email, password);
  
  await PrivacyLabsConsent.linkIdentity(
    email,
    method: IdentityLinkMethod.signup,
  );
}

4. iOS App Tracking Transparency (Optional) #

For iOS apps that use tracking, you need to request ATT permission:

import 'dart:io';
import 'package:theprivacylabs_consent/theprivacylabs_consent.dart';

Future<void> requestTrackingPermission() async {
  if (Platform.isIOS) {
    // Request ATT permission first
    final attStatus = await PrivacyLabsConsent.requestATTPermission();
    
    if (attStatus == ATTStatus.authorized) {
      // User allowed tracking, show privacy settings
      Navigator.pushNamed(context, '/privacy-settings');
    } else {
      // User denied tracking, set consent accordingly
      await PrivacyLabsConsent.setConsent(ConsentPreferences(
        analytics: false,
        marketing: false,
      ));
    }
  } else {
    // Android: just show privacy settings
    Navigator.pushNamed(context, '/privacy-settings');
  }
}

Note: ATT requires the app_tracking_transparency package for full support.

API Reference #

PrivacyLabsConsent #

Method Description
init(config) Initialize the SDK
getConsentStatus({syncWithServer}) Get current consent state
hasConsent(category) Check if user consented to a category
getCategories({lang}) Get available consent categories
setConsent(preferences) Update consent preferences
acceptAll() Accept all categories
withdrawConsent() Withdraw all consent
linkIdentity(userKey, {method}) Link consent to user identity
syncFromServer(userId) Sync consent from another device
requestATTPermission() Request iOS ATT permission
getATTStatus() Get iOS ATT status
clearLocalData() Clear local consent data

Types #

ConsentConfig

ConsentConfig({
  required String orgId,
  String apiBaseUrl = 'https://app.theprivacylabs.com',
  bool debug = false,
  void Function(ConsentState)? onConsentChange,
  void Function(Exception)? onError,
})

ConsentPreferences

ConsentPreferences({
  bool essential = true,
  bool analytics = false,
  bool marketing = false,
  bool performance = false,
})

ConsentState

ConsentState({
  required bool hasConsent,
  required ConsentPreferences preferences,
  DateTime? timestamp,
  DateTime? expiryDate,
  String? platform,
  String? deviceId,
  bool isSynced = false,
})

When a user logs in on a new device, their consent preferences are automatically synced:

  1. User gives consent on Device A (web or mobile)
  2. User logs in on Device B (Flutter app)
  3. SDK calls linkIdentity() with user's email
  4. Backend finds existing consent and syncs to Device B
  5. onConsentChange callback fires with synced preferences

This ensures consistent consent across all user devices.

Integration Checklist #

Before Launch #

  • ❌ Add SDK to pubspec.yaml
  • ❌ Initialize SDK in main.dart with orgId
  • ❌ Create Privacy Settings screen with category toggles
  • ❌ Add "Withdraw Consent" button that calls withdrawConsent() (clears local data + records to API)
  • ❌ Add "Privacy Settings" to app settings/profile menu

On User Events #

  • ❌ First app launch: Check consent status, show settings if needed
  • ❌ User login: Call linkIdentity(email, method: IdentityLinkMethod.login)
  • ❌ User signup: Call linkIdentity(email, method: IdentityLinkMethod.signup)
  • ❌ User logout: Optionally call clearLocalData()

SDK Integration #

  • ❌ Gate analytics/marketing SDKs based on consent state
  • ❌ Implement onConsentChange callback to enable/disable SDKs dynamically
  • ❌ See SDK Integration Recipes below for per-SDK examples

SDK Integration Recipes #

Important: Mobile SDKs are compiled into your app — you cannot "not load" them at runtime. Instead, consent controls whether each SDK collects data or not. Your app owns execution; Privacy Labs owns consent state + policy.

Firebase Analytics #

import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:theprivacylabs_consent/theprivacylabs_consent.dart';

// On app launch — set initial state
final consent = await PrivacyLabsConsent.getConsentStatus();
await FirebaseAnalytics.instance
    .setAnalyticsCollectionEnabled(consent?.preferences.analytics ?? false);

// On consent change — update dynamically
await PrivacyLabsConsent.init(ConsentConfig(
  orgId: 'your-org-id',
  onConsentChange: (state) async {
    await FirebaseAnalytics.instance
        .setAnalyticsCollectionEnabled(state.preferences.analytics);
  },
));

Firebase Crashlytics #

import 'package:firebase_crashlytics/firebase_crashlytics.dart';

// Gate on analytics (or performance) consent
await FirebaseCrashlytics.instance
    .setCrashlyticsCollectionEnabled(consent?.preferences.analytics ?? false);

Mixpanel #

import 'package:mixpanel_flutter/mixpanel_flutter.dart';

final mixpanel = await Mixpanel.init('YOUR_TOKEN', trackAutomaticEvents: false);

// On consent change
if (consent.preferences.analytics) {
  mixpanel.optInTracking();
} else {
  mixpanel.optOutTracking();
}

Adjust (Marketing Attribution) #

import 'package:adjust_sdk/adjust.dart';
import 'package:adjust_sdk/adjust_config.dart';

final adjustConfig = AdjustConfig('APP_TOKEN', AdjustEnvironment.production);

// Only enable if marketing consent given
if (consent?.preferences.marketing ?? false) {
  Adjust.start(adjustConfig);
} else {
  Adjust.setEnabled(false);
}

// On consent change
onConsentChange: (state) {
  Adjust.setEnabled(state.preferences.marketing);
}

AppsFlyer #

import 'package:appsflyer_sdk/appsflyer_sdk.dart';

// Gate on marketing consent
if (consent?.preferences.marketing ?? false) {
  appsflyerSdk.startSDK();
} else {
  appsflyerSdk.stop(true);
}

CleverTap / MoEngage (Marketing Push) #

// CleverTap
import 'package:clevertap_plugin/clevertap_plugin.dart';

if (consent?.preferences.marketing ?? false) {
  CleverTapPlugin.setOptOut(false);
} else {
  CleverTapPlugin.setOptOut(true);
}

// MoEngage
import 'package:moengage_flutter/moengage_flutter.dart';

if (consent?.preferences.marketing ?? false) {
  MoEngageFlutter.enableDataTracking();
} else {
  MoEngageFlutter.disableDataTracking();
}
// utils/consent_gate.dart
import 'package:theprivacylabs_consent/theprivacylabs_consent.dart';

Future<void> ifConsented(String category, Future<void> Function() action) async {
  final consent = await PrivacyLabsConsent.getConsentStatus();
  final prefs = consent?.preferences;
  bool allowed = false;

  switch (category) {
    case 'analytics':
      allowed = prefs?.analytics ?? false;
      break;
    case 'marketing':
      allowed = prefs?.marketing ?? false;
      break;
    case 'performance':
      allowed = prefs?.performance ?? false;
      break;
  }

  if (allowed) {
    await action();
  }
}

// Usage
await ifConsented('analytics', () => FirebaseAnalytics.instance.logEvent(name: 'purchase'));
await ifConsented('marketing', () => Adjust.trackEvent(adjustEvent));

License #

MIT

0
likes
140
points
22
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

DPDP-compliant consent management SDK for Flutter apps. Manage user privacy preferences across iOS and Android.

Homepage
Repository (GitHub)

License

MIT (license)

Dependencies

flutter, http, shared_preferences

More

Packages that depend on theprivacylabs_consent