Implementing Right to Erasure (GDPR) in Mobile Apps
"Delete Account" button — one of most underestimated requirements. App Store since 2022 requires all apps with accounts provide deletion directly in app (not via website form). Google Play — same. Both GDPR and CCPA grant users this right.
Technically "delete account" is not single SQL command. It's cascading process that if misimplemented either deletes incompletely or deletes what shouldn't be deleted.
What Must Be Deleted vs What Can't
Data falls into three categories:
Delete immediately: user profile (name, email, photo), action history, user-created content, auth tokens, push tokens, analytics data (via those systems' APIs).
Anonymize, don't delete: aggregated metrics (purchase count affects business stats), content other users interact with (can replace comments with "Deleted user").
Retain despite request: financial transactions (tax law requirements, usually 5–7 years), court order data, data needed for fraud investigation.
Deletion Process Architecture
Deletion shouldn't be synchronous — especially if data scattered across services. Correct scheme: request → queue → async execution → confirmation.
class AccountDeletionService(
private val deletionQueue: DeletionQueue,
private val notificationService: NotificationService
) {
suspend fun requestDeletion(userId: String, reason: DeletionReason?) {
// 1. Immediately block account — no new data
userRepository.setStatus(userId, UserStatus.PENDING_DELETION)
// 2. Revoke all active tokens
authTokenRepository.revokeAll(userId)
// 3. Queue deletion across services
deletionQueue.enqueue(
DeletionJob(
userId = userId,
requestedAt = System.currentTimeMillis(),
scheduledFor = System.currentTimeMillis() + GRACE_PERIOD_MS, // 30 days
steps = listOf(
DeletionStep.PROFILE_DATA,
DeletionStep.ANALYTICS_EVENTS,
DeletionStep.THIRD_PARTY_SDKS,
DeletionStep.BACKUP_ANONYMIZATION,
DeletionStep.AUDIT_LOGS_RETENTION
)
)
)
// 4. Notify user
notificationService.sendDeletionConfirmation(userId)
}
}
Grace period (30 days) — opportunity to restore account if user changes mind. During this period data frozen but not deleted. After expiry — auto-deletion.
Deletion From Third Parties
Each SDK that received user data must delete it:
class ThirdPartyDeletionStep(private val userId: String) : DeletionStep {
override suspend fun execute(): DeletionResult {
val results = coroutineScope {
listOf(
async { deleteFromAmplitude(userId) },
async { deleteFromBraze(userId) },
async { deleteFromFirebaseAnalytics(userId) },
async { deleteFromIntercom(userId) }
).awaitAll()
}
return if (results.all { it.success }) {
DeletionResult.Success
} else {
DeletionResult.PartialFailure(results.filter { !it.success })
}
}
private suspend fun deleteFromAmplitude(userId: String): ServiceDeletionResult {
// Amplitude GDPR API
val response = amplitudeApi.deleteUser(
AmplitudeDeletionRequest(userId = userId, requesterEmail = "[email protected]")
)
return ServiceDeletionResult("amplitude", response.isSuccessful)
}
}
Important: Firebase has no direct API for deleting specific user's Analytics data — only via resetAnalyticsData() on device + request via Firebase Console/API for server data. Account for this limitation in GDPR Firebase assessment as subprocessor.
Mobile Client: What Happens on Device
On deletion confirmation — immediate local cleanup, not awaiting server grace period:
func performLocalDeletion() {
// Keychain
let query: [String: Any] = [kSecClass as String: kSecClassGenericPassword]
SecItemDelete(query as CFDictionary)
// UserDefaults
UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
// Core Data / SQLite
try? FileManager.default.removeItem(at: coreDataURL)
try? FileManager.default.removeItem(at: sqliteURL)
// Caches
URLCache.shared.removeAllCachedResponses()
// Go to login screen
coordinator.navigateToLanding()
}
After local deletion app behaves as on first install. Server data deleted per schedule.
Verification Before Deletion
Can't allow attacker to delete someone else's account via intercepted request. Before execution:
- Re-authentication (password or biometry)
- Intent confirmation (not pop-up with identically-sized buttons)
- Email confirmation code for sensitive accounts
Completion Confirmation
Per GDPR: response to deletion request — within 30 days. User must receive confirmation deletion completed. If complete deletion impossible for legal reasons — explanation what exactly and why retained.
Timeline: basic implementation (UI + local deletion + server queue): 1–2 days. With all subprocessor deletions and documented GDPR process: 2–3 days.







