Cordova SDK - Data Privacy

Complying with Data Privacy Laws

Implement privacy-compliant data collection by notifying Singular of user consent choices for GDPR, CCPA, COPPA, and other consumer privacy regulations.

When users consent or decline to share their information with third parties, use Singular's privacy methods to communicate their choice. This ensures compliance with regulations like California Consumer Privacy Act (CCPA) and enables partners to respect user privacy preferences.

Learn More: See User Privacy and Limit Data Sharing for detailed information on how Singular processes privacy consent.


Limit Data Sharing

Control Third-Party Data Sharing

Notify Singular whether users have consented to share their personal data with third-party partners using the limitDataSharing() method.

Method Signature:

cordova.plugins.SingularCordovaSdk.limitDataSharing(
  shouldLimitDataSharing: boolean
): void

Parameters:

  • false: User has opted in and consented to share their data
  • true: User has opted out and does not consent to share their data

Important: While optional, this method affects attribution data sharing. Some partners only share complete attribution information when explicitly notified that users have opted in.

For complete method documentation, see limitDataSharing reference.


Usage Examples

Implement data sharing controls based on user privacy preferences.

JavaScript
document.addEventListener('deviceready', onDeviceReady, false);

function onDeviceReady() {
  // User has opted in to share their data
  var onUserOptedInToDataSharing = function() {
    cordova.plugins.SingularCordovaSdk.limitDataSharing(false);
    console.log('Data sharing enabled');
  };
  
  // User has opted out and declined to share their data
  var onUserOptedOutOfDataSharing = function() {
    cordova.plugins.SingularCordovaSdk.limitDataSharing(true);
    console.log('Data sharing limited');
  };
  
  // Set based on user preference
  var handlePrivacyConsent = function(userConsented) {
    // Pass inverse: false = opted in, true = opted out
    cordova.plugins.SingularCordovaSdk.limitDataSharing(!userConsented);
    
    console.log('Data sharing: ' + (userConsented ? 'Enabled' : 'Limited'));
  };
  
  // Example: Ask user for consent
  askUserForPrivacyConsent(function(consented) {
    handlePrivacyConsent(consented);
  });
}

function askUserForPrivacyConsent(callback) {
  // Show custom dialog to user
  if (confirm('Do you consent to share your data with third parties?')) {
    callback(true);
  } else {
    callback(false);
  }
}

How It Works:

Singular uses this setting in User Privacy Postbacks and passes it to partners who require it for regulatory compliance.


GDPR Compliance Methods

Manage user tracking consent and control SDK functionality to comply with GDPR (General Data Protection Regulation) and other privacy regulations.

Tracking Consent Management

TrackingOptIn

Record explicit user consent for tracking by sending a GDPR opt-in event to Singular servers.

Method Signature:

cordova.plugins.SingularCordovaSdk.trackingOptIn(): void

When to Use:

  • GDPR Compliance: Call when users explicitly consent to tracking in GDPR-regulated regions
  • Consent Recording: Marks users as having provided GDPR consent in Singular's systems
  • Default Behavior: Without this call, SDK continues tracking but doesn't specifically record consent

For complete method documentation, see trackingOptIn reference.


Implementation Example

Call trackingOptIn() after users accept tracking consent through your app's consent dialog.

JavaScript
document.addEventListener('deviceready', initializeGDPR, false);

function initializeGDPR() {
  checkStoredConsent();
}

function checkStoredConsent() {
  // Check if user has previously provided consent
  var consent = localStorage.getItem('gdpr_consent');
  
  if (consent === null) {
    // No stored preference - show consent dialog
    showGDPRConsentDialog();
  } else if (consent === 'true') {
    // User previously consented - apply setting
    onUserAcceptedTracking();
  }
}

function showGDPRConsentDialog() {
  // Show custom dialog to user
  var message = 'We would like your permission to track app usage and improve your experience.';
  
  if (confirm(message)) {
    onUserAcceptedTracking();
  } else {
    onUserDeclinedTracking();
  }
}

function onUserAcceptedTracking() {
  // Record user consent with Singular
  cordova.plugins.SingularCordovaSdk.trackingOptIn();
  console.log('User opted in to tracking');
  
  // Save preference locally
  localStorage.setItem('gdpr_consent', 'true');
}

function onUserDeclinedTracking() {
  console.log('User declined tracking');
  localStorage.setItem('gdpr_consent', 'false');
}

Tracking Control Methods

StopAllTracking

Completely disable all SDK tracking activities for the current user on this device.

Method Signature:

cordova.plugins.SingularCordovaSdk.stopAllTracking(): void

Critical Warning: This method permanently disables the SDK until resumeAllTracking() is called. The disabled state persists across app restarts and can only be reversed programmatically.

Behavior:

  • Immediate Effect: Stops all tracking, event reporting, and data collection instantly
  • Persistent State: Remains disabled even after app closes and reopens
  • No Automatic Reset: Must explicitly call resumeAllTracking() to re-enable

For complete method documentation, see stopAllTracking reference.


Implementation Example

Stop tracking when users decline consent or opt out through privacy settings.

JavaScript
// User declined all tracking
function onUserDeclinedTracking() {
  cordova.plugins.SingularCordovaSdk.stopAllTracking();
  console.log('All tracking stopped');
  
  // Store preference
  localStorage.setItem('tracking_enabled', 'false');
}

// Handle user opt-out from settings menu
function handlePrivacySettingsChange(trackingEnabled) {
  if (!trackingEnabled) {
    cordova.plugins.SingularCordovaSdk.stopAllTracking();
    console.log('Privacy settings: Tracking disabled');
    localStorage.setItem('tracking_enabled', 'false');
  }
}

ResumeAllTracking

Re-enable tracking after it was stopped with stopAllTracking().

Method Signature:

cordova.plugins.SingularCordovaSdk.resumeAllTracking(): void

Use Cases:

  • Consent Change: User changes privacy preferences and opts back into tracking
  • Privacy Settings: User updates consent through app settings menu
  • Regional Compliance: Re-enable tracking when user moves to non-regulated regions

For complete method documentation, see resumeAllTracking reference.


Implementation Example

Resume tracking when users opt back in or update their privacy preferences.

JavaScript
// User opted back in to tracking
function onUserResumedTracking() {
  cordova.plugins.SingularCordovaSdk.resumeAllTracking();
  console.log('Tracking resumed');
  
  // Update stored preference
  localStorage.setItem('tracking_enabled', 'true');
}

// Handle consent update from settings
function handlePrivacySettingsChange(trackingEnabled) {
  if (trackingEnabled) {
    cordova.plugins.SingularCordovaSdk.resumeAllTracking();
    console.log('Privacy settings: Tracking enabled');
    localStorage.setItem('tracking_enabled', 'true');
  }
}

IsAllTrackingStopped

Check whether tracking has been disabled for the current user.

Method Signature:

cordova.plugins.SingularCordovaSdk.isAllTrackingStopped(
  success: Function
): void

Returns:

  • true: Tracking is currently stopped via stopAllTracking()
  • false: Tracking is active (either never stopped or resumed)

For complete method documentation, see isAllTrackingStopped reference.


Implementation Example

Check tracking status to sync UI state with SDK tracking state.

JavaScript
document.addEventListener('deviceready', initializePrivacyUI, false);

function initializePrivacyUI() {
  updatePrivacyUI();
}

// Check current tracking status
function isTrackingEnabled(callback) {
  cordova.plugins.SingularCordovaSdk.isAllTrackingStopped(function(isStopped) {
    callback(!isStopped);
  });
}

// Display privacy status in settings
function getPrivacyStatusText(callback) {
  cordova.plugins.SingularCordovaSdk.isAllTrackingStopped(function(isStopped) {
    var text = isStopped ? 'Tracking: Disabled' : 'Tracking: Enabled';
    callback(text);
  });
}

// Sync UI with tracking state
function updatePrivacyUI() {
  cordova.plugins.SingularCordovaSdk.isAllTrackingStopped(function(isStopped) {
    var statusElement = document.getElementById('tracking-status');
    var toggleElement = document.getElementById('tracking-toggle');
    
    if (statusElement) {
      statusElement.textContent = isStopped ? 'Tracking: Disabled' : 'Tracking: Enabled';
    }
    
    if (toggleElement) {
      toggleElement.checked = !isStopped;
    }
    
    console.log('Current tracking state: ' + (isStopped ? 'Stopped' : 'Active'));
  });
}

// Handle toggle change from UI
function onTrackingToggleChanged(enabled) {
  if (enabled) {
    cordova.plugins.SingularCordovaSdk.resumeAllTracking();
  } else {
    cordova.plugins.SingularCordovaSdk.stopAllTracking();
  }
  
  updatePrivacyUI();
}

Children's Privacy Protection

Implement COPPA (Children's Online Privacy Protection Act) compliance and protect children's privacy by notifying Singular when users are under 13 years old.

TrackingUnder13

Enable Child Privacy Protections

Notify Singular that the user is under 13 years old to comply with COPPA and other child privacy regulations.

Method Signature:

cordova.plugins.SingularCordovaSdk.trackingUnder13(): void

Compliance Requirements:

  • COPPA Compliance: Required for apps that collect data from children under 13 in the United States
  • Age-Gated Content: Use when users identify themselves as under 13 during registration or age verification
  • Restricted Tracking: Limits data collection to comply with children's privacy protection laws

For complete method documentation, see trackingUnder13 reference.


Implementation Example

Call trackingUnder13() immediately after determining the user is under 13 through age verification.

JavaScript
document.addEventListener('deviceready', initializeCOPPA, false);

function initializeCOPPA() {
  // Check if user's age was previously verified
  var ageCategory = localStorage.getItem('user_age_category');
  
  if (ageCategory === 'under_13') {
    applyChildPrivacyProtections();
  }
}

// User identified as under 13
function onUserUnder13() {
  cordova.plugins.SingularCordovaSdk.trackingUnder13();
  console.log('COPPA mode enabled for user under 13');
  
  // Store age category for app restart
  localStorage.setItem('user_age_category', 'under_13');
}

// Call after age verification
function onAgeVerified(userAge) {
  if (userAge < 13) {
    cordova.plugins.SingularCordovaSdk.trackingUnder13();
    console.log('COPPA restrictions applied');
    
    // Also limit advertising identifiers
    cordova.plugins.SingularCordovaSdk.setLimitAdvertisingIdentifiers(true);
    
    localStorage.setItem('user_age_category', 'under_13');
    
    alert('Special privacy protections have been applied to your account.');
  } else {
    localStorage.setItem('user_age_category', 'adult');
    console.log('Adult account - standard tracking');
  }
}

// Example: Age verification form
function handleAgeSubmit() {
  var ageInput = document.getElementById('age-input');
  var userAge = parseInt(ageInput.value, 10);
  
  if (isNaN(userAge) || userAge < 1 || userAge > 120) {
    alert('Please enter a valid age.');
    return;
  }
  
  onAgeVerified(userAge);
}

// Apply all child privacy protections
function applyChildPrivacyProtections() {
  cordova.plugins.SingularCordovaSdk.trackingUnder13();
  cordova.plugins.SingularCordovaSdk.setLimitAdvertisingIdentifiers(true);
  console.log('Child privacy protections applied');
}

Best Practice: Call trackingUnder13() as early as possible after determining the user's age. Combine with setLimitAdvertisingIdentifiers(true) for comprehensive child privacy protection.


Complete Privacy Implementation

Implement comprehensive privacy management covering GDPR, CCPA, and COPPA compliance with persistent storage and UI synchronization.

Full Implementation Example

Privacy Manager Module

Create a reusable privacy management module that handles all privacy settings initialization and persistence.

JavaScript
// Privacy Manager Module
var PrivacyManager = {
  // Storage keys
  PREF_USER_CONSENT: 'privacy_user_consent',
  PREF_DATA_SHARING: 'privacy_data_sharing',
  PREF_AGE_CATEGORY: 'user_age_category',
  
  /**
   * Initialize privacy settings on app startup
   */
  initialize: function() {
    var hasUserConsent = this.getUserConsent();
    var allowDataSharing = this.getDataSharingPreference();
    var ageCategory = this.getAgeCategory();
    
    // Apply age-based restrictions first
    if (ageCategory === 'under_13') {
      cordova.plugins.SingularCordovaSdk.trackingUnder13();
      cordova.plugins.SingularCordovaSdk.setLimitAdvertisingIdentifiers(true);
      console.log('COPPA restrictions applied on startup');
    }
    
    // Apply stored tracking preference
    if (hasUserConsent) {
      cordova.plugins.SingularCordovaSdk.trackingOptIn();
      cordova.plugins.SingularCordovaSdk.resumeAllTracking();
      console.log('Privacy initialized: Tracking enabled with consent');
    } else {
      cordova.plugins.SingularCordovaSdk.stopAllTracking();
      console.log('Privacy initialized: Tracking disabled');
    }
    
    // Set data sharing preference (inverse logic)
    cordova.plugins.SingularCordovaSdk.limitDataSharing(!allowDataSharing);
    
    console.log('Privacy initialized: consent=' + hasUserConsent + ', sharing=' + allowDataSharing);
  },
  
  /**
   * User accepts tracking via consent dialog
   */
  onUserAcceptedTracking: function() {
    this.saveUserConsent(true);
    
    cordova.plugins.SingularCordovaSdk.trackingOptIn();
    cordova.plugins.SingularCordovaSdk.resumeAllTracking();
    
    console.log('User accepted tracking');
  },
  
  /**
   * User declines tracking
   */
  onUserDeclinedTracking: function() {
    this.saveUserConsent(false);
    
    cordova.plugins.SingularCordovaSdk.stopAllTracking();
    
    console.log('User declined tracking');
  },
  
  /**
   * User updates data sharing preference
   */
  setDataSharingEnabled: function(enabled) {
    this.saveDataSharingPreference(enabled);
    
    // Note: LimitDataSharing uses inverse logic
    // false = data sharing enabled, true = data sharing limited
    cordova.plugins.SingularCordovaSdk.limitDataSharing(!enabled);
    
    console.log('Data sharing: ' + (enabled ? 'Enabled' : 'Limited'));
  },
  
  /**
   * Check if tracking is currently enabled
   */
  isTrackingEnabled: function(callback) {
    cordova.plugins.SingularCordovaSdk.isAllTrackingStopped(function(isStopped) {
      callback(!isStopped);
    });
  },
  
  /**
   * Get current privacy status as readable text
   */
  getPrivacyStatus: function(callback) {
    var self = this;
    
    this.isTrackingEnabled(function(isEnabled) {
      var dataSharingEnabled = self.getDataSharingPreference();
      var ageCategory = self.getAgeCategory();
      
      var status = 'Tracking: ' + (isEnabled ? 'Enabled' : 'Disabled') + '\n';
      status += 'Data Sharing: ' + (dataSharingEnabled ? 'Enabled' : 'Limited');
      
      if (ageCategory === 'under_13') {
        status += '\nCOPPA: Restrictions Applied';
      }
      
      callback(status);
    });
  },
  
  /**
   * Set user's age and apply appropriate protections
   */
  setUserAge: function(age) {
    if (age < 13) {
      cordova.plugins.SingularCordovaSdk.trackingUnder13();
      cordova.plugins.SingularCordovaSdk.setLimitAdvertisingIdentifiers(true);
      localStorage.setItem(this.PREF_AGE_CATEGORY, 'under_13');
      console.log('Age set to under 13 - COPPA protections applied');
    } else {
      localStorage.setItem(this.PREF_AGE_CATEGORY, 'adult');
      console.log('Age set to adult - standard tracking');
    }
  },
  
  // Private helper methods
  getUserConsent: function() {
    var value = localStorage.getItem(this.PREF_USER_CONSENT);
    return value === 'true';
  },
  
  saveUserConsent: function(consent) {
    localStorage.setItem(this.PREF_USER_CONSENT, consent.toString());
  },
  
  getDataSharingPreference: function() {
    var value = localStorage.getItem(this.PREF_DATA_SHARING);
    return value === 'true';
  },
  
  saveDataSharingPreference: function(enabled) {
    localStorage.setItem(this.PREF_DATA_SHARING, enabled.toString());
  },
  
  getAgeCategory: function() {
    return localStorage.getItem(this.PREF_AGE_CATEGORY);
  }
};

// Initialize on device ready
document.addEventListener('deviceready', function() {
  PrivacyManager.initialize();
}, false);

Key Implementation Guidelines

Best Practices:

  • Persistent Storage: Save user preferences using localStorage or a secure storage solution
  • Early Initialization: Apply privacy settings immediately after SDK initialization
  • UI Sync: Keep settings UI synchronized with actual SDK state using isAllTrackingStopped()
  • Clear Communication: Provide clear, accessible privacy controls in app settings
  • Inverse Logic: Remember that limitDataSharing(false) means data sharing is enabled, while true means it's limited
  • COPPA Priority: Apply children's privacy protections (trackingUnder13()) before other privacy settings
  • Compliance Documentation: Maintain records of when and how users provide or revoke consent

Verification Checklist

Ensure your privacy implementation meets compliance requirements:

  1. Consent Collection: Users are asked for explicit consent before tracking begins
  2. Consent Recording: Call trackingOptIn() when users provide GDPR consent
  3. Data Sharing Controls: Use limitDataSharing() to communicate user preferences to partners
  4. Opt-Out Mechanism: Users can stop tracking via stopAllTracking() from privacy settings
  5. Age Verification: Implement age gates and call trackingUnder13() for children
  6. Persistent Settings: Privacy preferences are saved and reapplied on app restart
  7. UI Transparency: Privacy settings screen clearly displays current tracking status