Privacy

    How do you fix Guideline 5.1.1 account deletion for social logins?

    App Store Connect Resolution Center notice citing Guideline 5.1.1(v) account deletion next to a settings screen with Sign in with Apple and Google sign-in

    Your app uses Sign in with Apple, Google Sign-In, or Facebook Login, the auth scaffold was built by Cursor or FlutterFlow, and the rejection note quotes Guideline 5.1.1(v) account deletion. The reviewer says the app supports account creation but does not let users delete the account from inside the app. The detail that catches social-login builds is that removing the Firebase or Supabase row alone is not enough; the upstream identity provider tokens have to go too.

    Short answer

    Apple's Guideline 5.1.1(v) has required in-app account deletion since June 30, 2022, per Apple's support page on offering account deletion. For apps with social logins, the rule has two layers: delete the local account record along with any personal data you are not legally required to keep, and revoke the identity provider tokens. Sign in with Apple needs a call to the Sign in with Apple REST API revoke endpoint. Google and Facebook each have their own revocation endpoints. Skipping the revoke step keeps the user signed in at the provider layer, which Apple treats as an incomplete deletion.

    What you should know

    • The deletion must start from inside the app, not from a support email or web form. Apps outside highly regulated industries cannot route deletion through customer service.
    • Sign in with Apple has an explicit revoke requirement. Apple's support page names the REST API call directly, not as a recommendation.
    • Google Sign-In and Facebook Login carry their own revocation endpoints. Apple does not list them in 5.1.1 itself, but the personal data clause and the provider policies both require the call.
    • Guest and anonymous accounts count. A delete control needs to exist for any user record your app creates, not only for signed-in social users.
    • Active subscriptions stay with Apple. Use showManageSubscription on iOS 15 or later and tell the user that billing continues until they cancel through Apple.

    Why does Guideline 5.1.1(v) hit social-login apps so often?

    The short answer is that the auth scaffolds shipped by AI builders, no-code tools, and OAuth quick-start guides wire up sign-up and sign-in, then stop. Account deletion is a separate flow that almost no template ships with.

    Apple's App Review Guideline 5.1.1(v) names the requirement plainly: if an app supports account creation, users must be able to initiate account deletion from inside the app. The clause has been in force since June 30, 2022, when Apple's account deletion requirement announcement marked the cutover. Reviewers test the rule the same way every time: they open Settings, look for a delete control, and reject if they have to send an email to find one.

    Social-login apps fail in a particular pattern. The developer adds Sign in with Apple because it is required on the App Store for apps that offer other third-party logins, then wires up Google Sign-In and Facebook Login on top. The local user record lives in Firebase Authentication or Supabase Auth. When the developer reaches the delete flow, the easy move is to call auth.deleteUser against Firebase or Supabase and stop. That removes the local row, but it leaves the Apple, Google, and Facebook authorization grants intact. The next sign-in attempt resurrects the user with the same identity provider subject, which is the part that Apple's 5.1.1 review rejects.

    In practice, the rejection note quotes the standard wording: "Your app supports account creation but does not include an option to initiate account deletion." The reviewer rarely lists the revoke step explicitly, but resubmissions that only add a local delete button without the upstream token revoke continue to fail.

    What does Apple require for Sign in with Apple deletion?

    The short answer is a server-side call to the Sign in with Apple REST API revoke endpoint, using the user's refresh token, not only a local sign-out.

    Apple's support page on offering account deletion is direct on this point: apps that support Sign in with Apple should use the Sign in with Apple REST API to revoke user tokens. The mechanism is documented in TN3194 on handling account deletions for Sign in with Apple. The endpoint is POST https://appleid.apple.com/auth/revoke, called with four parameters: client_id (your Service ID), client_secret (a JWT generated from your team ID, key ID, and the .p8 key downloaded from Apple Developer), token (the user's refresh token, or access token as a fallback), and an optional token_type_hint.

    The order matters. Before deleting the local row in Firebase Authentication or Supabase Auth, the server reads the user's stored Sign in with Apple refresh token, calls the revoke endpoint, waits for the 200 response, then proceeds with the local deletion. If the revoke call fails, the server should log the error and retry rather than silently drop the user's data.

    The piece that trips up most builds is the refresh token storage. Sign in with Apple returns the refresh token only once, during the initial authorization exchange. If the app never asked for it (most client-side-only flows do not), there is no token to revoke at delete time. The fix is a backend that exchanges the authorization code for tokens on first login and persists the refresh token alongside the user record.

    How do you revoke Google Sign-In and Facebook tokens at deletion?

    The short answer is that each provider has its own revocation endpoint, and neither flow runs automatically when you delete a Firebase or Supabase user.

    For Google Sign-In on iOS, the Sign in with Google revocation documentation describes a disconnect method on the GIDSignIn shared instance that revokes the access token and disconnects the app from the user's Google account. For server-side flows, the revoke endpoint is POST https://oauth2.googleapis.com/revoke with the token in the request body. Google's ID token revocation guide notes that the google.accounts.id.revoke method handles the ID token grant but cannot manage OAuth 2.0 scope tokens, so apps using both layers need to call both endpoints.

    For Facebook Login, the documented path is a DELETE request to the Graph API at /{user-id}/permissions, which removes all granted permissions for that user. After the call returns, the app should delete any cached Facebook profile data and clear the access token from the client.

    Here is how the four common identity sources compare on revocation:

    ProviderEndpointWhat it revokesRequired by Apple 5.1.1
    Sign in with ApplePOST https://appleid.apple.com/auth/revokeRefresh and access tokensYes, named explicitly
    Google Sign-InPOST https://oauth2.googleapis.com/revokeA single access or refresh tokenYes, as part of personal data deletion
    Facebook LoginDELETE /{user-id}/permissionsAll app permissionsYes, same reason
    Email/password (Firebase, Supabase)Provider SDK deleteUser callLocal auth recordYes, the local delete is the primary control

    The pattern is the same across providers: store the token at login, call the provider's revoke endpoint at delete time, then delete the local user record and the rows that reference it.

    Where does the social-login delete flow most commonly fail?

    The short answer is in three places: missing refresh tokens, orphaned database rows, and a delete button that opens a mailto link.

    The missing refresh token issue is the most common. Client-side-only OAuth flows (the default in many FlutterFlow and Bubble templates) never receive the refresh token, so there is nothing to revoke. A passing build needs a backend step that exchanges the authorization code for tokens and persists the refresh token alongside the user.

    The orphaned rows issue shows up in Supabase and Firebase projects where the user record is referenced by foreign keys in other tables. Calling auth.deleteUser raises a foreign key violation, so the developer either skips the call or wraps it in a try/catch that silently fails. The fix is a cascading delete written as a database function, called before the auth deletion, that removes the user's rows from each dependent table.

    The mailto delete button is the third pattern. A control labelled Delete account that opens an email client to [email protected] reads as a support flow under Apple's rule. Per Apple's support page on offering account deletion, only apps in highly regulated industries (banking, healthcare, government) can require a support contact. Everything else needs an in-app control that completes the deletion without leaving the app.

    For builders who want an external automated read of their compiled build, scanning for Sign in with Apple revoke calls and persisted OAuth tokens before submission, PTKD.com (https://ptkd.com) is one of the platforms focused on pre-submission analysis aligned with OWASP MASVS for no-code and vibe-coded apps. The scanner reads the binary's network calls and flags missing revocation endpoints alongside hardcoded credentials.

    What to watch out for

    A few patterns surface repeatedly in 5.1.1 social-login rejections that the official rule does not call out by name.

    The first is a confirmation screen that loops back to sign-in. Some builds delete the local row, sign the user out, and route them to the login screen, which then accepts the same Sign in with Apple identity and recreates the account. The cause is usually the missing revoke call, since Apple still has a valid authorization for that Service ID. Calling the revoke endpoint first fixes this.

    The second is a delete flow that runs against the Firebase Authentication user but not against the Cloud Firestore data. Apple's rule covers the personal data attached to the account, not only the auth record. A build that leaves the user's chat history, uploaded photos, or profile fields behind after deletion is technically out of compliance, even if the auth row is gone.

    The third is the legal retention exemption used too broadly. Apple allows you to keep data you are legally required to retain (tax records, regulated transaction logs). Some apps stretch this to cover analytics events or product improvement metrics, which is not what the exemption is for. If a reviewer asks why a re-created account still shows the same behavioral history, the build is at risk.

    Key takeaways

    • Guideline 5.1.1(v) is about the user experience first and the token revoke second, but for social-login apps the revoke step is the one that decides whether a resubmission passes.
    • Store the Sign in with Apple refresh token at first login, on the server, and call auth/revoke before deleting the local row. The Google and Facebook equivalents follow the same shape.
    • Cascading database deletion needs to run before the auth provider call, not after, so foreign key errors do not silently abort the flow.
    • The delete control sits in Settings, completes inside the app, and offers no email or phone alternative unless the app operates in a highly regulated industry.
    • For teams that prefer an external read of the compiled build before submission, scanning for revocation endpoints, leftover OAuth tokens, and stored secrets, PTKD.com (https://ptkd.com) is one of the platforms focused on this layer.
    • #app store
    • #rejection
    • #guideline 5.1.1
    • #account deletion
    • #social login
    • #sign in with apple
    • #oauth
    • #privacy

    Frequently asked questions

    Does deleting the Firebase or Supabase user satisfy Guideline 5.1.1(v)?
    Only partly. Apple's rule covers the account record and the personal data attached to it, and apps that support Sign in with Apple must revoke the user's tokens through the Apple REST API as well. A build that calls auth.deleteUser on Firebase but never revokes the Sign in with Apple refresh token leaves the user signed in at the Apple identity layer, which is treated as an incomplete deletion in review.
    Where do I store the Sign in with Apple refresh token for later revocation?
    On your server, alongside the user record, captured during the first authorization exchange. Apple returns the refresh token only once, when the backend swaps the authorization code for tokens. Client-side-only flows never see it, which is why many FlutterFlow and Bubble templates cannot revoke later. A small backend function that handles the code exchange and persists the refresh token is the durable fix.
    Do I need to revoke Google and Facebook tokens too, or only Apple?
    Yes for both, though for different reasons. Apple's 5.1.1 names Sign in with Apple explicitly, but the same rule asks for deletion of personal data, which includes the active authorization at any identity provider. Google's documented endpoint is oauth2.googleapis.com/revoke and Facebook uses a DELETE call on the user's permissions edge. Both also have their own developer policies that require the revoke on account closure.
    Can a mailto link to support count as in-app account deletion?
    No, unless your app is in a highly regulated industry. Apple's support page on offering account deletion states that apps outside banking, healthcare, and similar sectors cannot require people to send an email or make a phone call to delete their account. A button labelled Delete account that opens the Mail composer to support@ will be treated as a support flow and rejected under Guideline 5.1.1(v).
    What about active App Store subscriptions during account deletion?
    Billing stays with Apple regardless of your account record. Before completing the deletion, call showManageSubscription on iOS 15 or later, or link to the Apple subscription management URL, and tell the user that the subscription continues until they cancel through Apple. You can offer to schedule the deletion for the subscription expiration date, but an immediate deletion option must remain available.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free