GDPR Art. 7(3) grants users the right to withdraw consent at any time, and withdrawal must be as easy as giving consent. CCPA §1798.120 grants California consumers the right to opt out of the sale or sharing of personal information. An analytics opt-out toggle that exists in Settings but does not actually stop data collection is deceptive — and regulators have specifically targeted this pattern, where consent signals are recorded but not enforced. The ePrivacy Directive Art. 5(3) further requires that tracking cookies or equivalent tracking mechanisms require prior consent in EU member states. An analytics SDK that runs regardless of the user's stored preference treats user choice as cosmetic.
Low because the user retains visibility of the broken opt-out, and enforcement requires regulators to test the feature — but a non-functional opt-out is a direct GDPR Art. 7(3) and CCPA §1798.120 violation.
Implement the opt-out as a gate on the analytics call site, not just a stored preference. The SDK must not send any event when analyticsEnabled is false.
import AsyncStorage from '@react-native-async-storage/async-storage'
export async function trackEvent(name: string, props?: Record<string, unknown>) {
const pref = await AsyncStorage.getItem('analyticsOptOut')
if (pref === 'true') return // User opted out — do not send
analytics.track(name, props)
}
// In Settings screen
async function handleOptOutToggle(optOut: boolean) {
await AsyncStorage.setItem('analyticsOptOut', String(optOut))
if (optOut) {
analytics.reset() // Flush queued events and clear identity
}
}
Also call analytics.reset() on opt-out to flush any queued events and disassociate the device ID — some SDKs batch events and will send opted-out data if only initialization is gated.
ID: mobile-permissions-privacy.data-handling.analytics-opt-out
Severity: low
What to look for: Search for analytics opt-out toggles in Settings screens. Enumerate all analytics SDK initialization calls and check whether each checks an opt-out flag before sending data. Quote the actual toggle implementation (or note its absence).
Pass criteria: At least 1 toggle exists in settings to disable analytics/tracking. When toggled off, at least 100% of analytics calls check the opt-out preference and skip data collection. Report the count even on pass: "Found N analytics call sites, all check opt-out flag."
Fail criteria: No analytics opt-out available to users. OR toggle exists but analytics still runs when disabled (opt-out flag not checked before sending events).
Skip (N/A) when: App does not use analytics or crash reporting (no analytics SDK found in dependencies).
Detail on fail: Quote the analytics initialization code. "No option to disable analytics in settings" or "Analytics disabled setting exists but analytics events still sent when disabled"
Remediation: Allow users to opt out of analytics:
// In settings
const [analyticsEnabled, setAnalyticsEnabled] = useState(true)
const toggleAnalytics = async (enabled) => {
setAnalyticsEnabled(enabled)
await AsyncStorage.setItem('analyticsEnabled', String(enabled))
if (enabled) {
initAnalytics()
} else {
disableAnalytics()
}
}
// When tracking events
async function trackEvent(eventName) {
const analyticsEnabled = await AsyncStorage.getItem('analyticsEnabled')
if (analyticsEnabled !== 'false') {
analytics.track(eventName)
}
}