firebase error when deleting user account "This operation is sensitive and requires recent authentication. Log in again before retrying this request."
Asked Answered
H

5

17

When I want to delete a firebase user account in my application, the operation passes normally if the user has recently logged but after a period of time if I try to delete the user I get this error "This operation is sensitive and requires recent authentication. Log in again before retrying this request." Normally the firebase refresh the user session automatically but I didn't find why he want the user to log again and even the value of Auth.auth().currentUser is not nil. Thank you for your help ! this is my code to delete the user account :

@objc func deleteAccountAction(){
self.showProgressView()
let user = Auth.auth().currentUser
let id=Auth.auth().currentUser?.uid
self.refProducts.child(id!).removeValue { error, _ in
    if(error != nil){
        print("firebase remove error")
        print(error?.localizedDescription.description ?? nil)
        self.dismissHUD(isAnimated: true)
    }
    else{
        self.refUsers.child(id!).removeValue { error, _ in
            if(error != nil){
                print("firebase remove error")
                print("error while deleting user from firebase: "+error!.localizedDescription)
                self.dismissHUD(isAnimated: true)    
            }
            else {

                user?.delete { error in
                    if  error != nil {
                        print("error while deleting user:" + error!.localizedDescription)
                        self.dismissHUD(isAnimated: true)
                    } else {

                       UserDefaults.standard.removeObject(forKey: "USER_UID")
                                                                               UserDefaults.standard.synchronize
                                    self.dismissHUD(isAnimated: true)
                                    let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "StartingViewController") as! StartingViewController
                                    nextVC.isAccoundDeleted=true
                                    GlobalVar.user=nil
                                    self.navigationController?.pushViewController(nextVC, animated: true)
                        }
                    }
                }
            }
        }
    }
}
Hyalite answered 16/6, 2019 at 9:13 Comment(0)
P
13

For certain sensitive operations (such as changing the user's password, or deleting the user account), Firebase requires that the user has recently signed in. If the user hasn't signed in recently when you try to perform such an operation, Firebase throws the exception you get.

When you get this exception, you should ask the user to re-enter their credentials, and retry the operation.

From the documentation on handling errors:

[Deleting a user account] is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, reauthenticate the user by invoking reauthenticateWithCredential:completion: on FIRUser.

Puerilism answered 16/6, 2019 at 15:4 Comment(3)
Hello, I have a same situation when i'm linking Phone Auth to Email Auth. How can i reauthenticate a phone user?Surveying
Do you know how recent is "recently" in "recently signed in"? Seconds, minutes, hours? I'd need this for debugging purposes.Orientalize
really? I show my user that he is logged in. and if he want to delete i have to force him to log in again? Suspicous in my and user eyes. Although it's breaking my hole UI. Any way to bypass this without the need for a extra cloud function i really don't want this.Archibaldo
M
8

In addition to Frank van's answer, time span for that is 5 minutes. After 5 minutes of login you cannot do such operations.

you can refer FIRAuthErrorCode (check out error code 17014 : FIRAuthErrorCodeRequiresRecentLogin = 17014)

Martinsen answered 16/9, 2021 at 11:5 Comment(2)
You say the time span is 5 minutes. Do you have a source for this? Any documentation?Thracian
@Finni, firebase.google.com/docs/reference/ios/firebaseauth/api/… - check code 17014's descriptionMartinsen
T
0

Here is a workaround: Make a call to a cloud function that performs the user account deletion and sign out the client. You must ensure proper guards for this cloud function so that it is not maliciously used.

Show courtesy to your users. Offer them with a proper dialog showing that this is irreversible and all relevant user data will be deleted permanently. Only call the function if the user accepts the consequences.

PSA edit: Although this approach will work, it will have an improper risk imposed on your user profile and data. The requirement to have the user sign in again for the delete account procedure serves a higher objective which is an additional layer of protection for the user account. By bypassing it as the solution suggests you are imposing a risk that another actor using the device will be able to delete the account without any additional checks. it is a procedure that is irreversible so if it was done by mistake then there is no way to go back.

Trochaic answered 19/9, 2022 at 6:5 Comment(3)
Improving on this solution: Instead of signing out the user, listen to FirebaseAuth.instance.userChanges() and do the signout there.Trochaic
IMHO, the cloud function defeats the purpose that this Firebase design is serving, this requirement is in place for higher security for the users. I don't think bypassing it would be such a good idea.Milkweed
You are right Amir. I will update the solution to share this concern as well. thx.Trochaic
L
0

To handle this, you can use Firebase UI Auth's showReauthenticateDialog() function in the firebase_ui_auth package. This provides a pre-built, customizable UI for re-authentication that works with various sign-in methods. After re-authentication is complete, you should be able to call the account deletion function.

There's no good documentation that I could find, but you can view the function here.

Here's my implementation:

initiateAccountDeletion() async {
User? user = _auth.currentUser;
try {
  await user.delete();
} on FirebaseAuthException catch (e, stackTrace) {
  if (e.code == 'requires-recent-login') {
    // Show re-authentication dialog
    await firebase_us_auth.showReauthenticateDialog(
      context: Get.context!,
      providers: [
        firebase_us_auth.EmailAuthProvider(),
        GoogleProvider(clientId: Firebase.app().options.iosClientId!),
        AppleProvider(),
      ],
      auth: _auth,
    );
    // After successful re-authentication, try deleting the account again
    await user.delete();
  } else {
    Get.snackbar(
      'Error',
      'Failed to delete account: ${e.message}',
    );
    logger.e('Failed to delete account', e, stackTrace);
  }
} catch (e, stackTrace) {
  Get.snackbar(
    'Error',
    'An unexpected error occurred. Please try again or contact support.',
  );
  logger.e('Failed to delete account', e, stackTrace);
}

}

Liquesce answered 13/7 at 5:25 Comment(0)
A
-7

What you can do (its probably the most easy way) is to save login and password of the user in the local storage when they log in first time (for example using AsyncStorage) and once they want to delete the account log them in again without needing them to reenter credentials shortly before you delete the account. They wont even noticed you logged them in again before deleting the account.

Im not a security expert but the password and email would be stored localy without access to the outside world so I do not see any concerns about security issues there.

Once you delete the app, the local storage is gone anyways, at least with AsyncStorage. Once you logout a user and use another account, the new account credentials would overwrite the old ones from the local storage.

Amontillado answered 6/10, 2021 at 19:4 Comment(2)
Storing any kind of password is never a good idea. If I suggested your solution in front of our security team they will eat me alive 😀Trochaic
@Trochaic I can feel the slap in my face :D Got your point sir, I still have much to learn.Amontillado

© 2022 - 2024 — McMap. All rights reserved.