0

I am using angular, and have an application that stores user details, and login info. When trying to delete a user, I am first deleting all the user related information. Then asking the user to re-authenticate themselves, after authentication, user gets logged out, and their basic details fetched to show profile id deleted followed by their sign-in info using user.delete().

All this works as expected, but at the end I am getting an error. Why am I am getting this error even when I have already logged out the user of the application.

Error Message: {code: "auth/user-token-expired", message: "The user's credential is no longer valid. The user must sign in again.", a: null}

My code -

  deleteAccount(){
    var userToDelete = firebase.auth().currentUser;
    this.logout();
    this.store.dispatch(UI.StartAppLoad({status:'Deleting User Details...'}));

    this.userService.DeleteUser(userToDelete.uid)
    .then((res)=>{
      console.log(res);
    }).catch(this.HandleError.bind(this));

    userToDelete.delete().then(
      (res)=>{
        console.log(res);
        this.uiService.showSnackbar('User Account Deleted',null,3000);
        this.store.dispatch(UI.LoadApp());
      }
    ).catch(this.HandleError.bind(this));
  }

  logout() {
    this.afAuth.signOut();
  }

where, HandleError is used to display the Error Message in a snackbar.

deleteAccount() is called after the user successfully authenticates themselves.

Instead of getting the error message displayed, I want to display the message 'User Account Deleted'.

Entire Flow -

  onDeleteAccount(){
    const confirmResult = this.uiService.showConfirm({
      isDanger:true,
      title:'Delete Account?',
      content:'All your user account data will be permamnently deleted.'+
              ' You will need to create a new account later. Are you sure you want to continue?',
      okText:'Delete'
    });
    confirmResult.subscribe(async isDelete=>{
      if(isDelete){
        this.store.dispatch(UI.StartAppLoad({status:'Deleting Excercise Data...'}));
        const isResetDone = await this.trainingService.resetPastExercise();
        if(isResetDone){
          this.store.dispatch(UI.StartAppLoad({status:'Deleting Follow list...'}));
          this.userService.clearFollowList();
          this.authService.actionToPerform.next(actions.Delete_Account);
          this.store.dispatch(UI.LoadApp());
          this.router.navigate([AppRoutes.ReAuthenticate]);
        }
      }
    });
  }

Authenticate Page's submit() method:

this.authService.reauthenticate({
  email:form.value.email,
  password:form.value.password
});

this.authService.deleteAccount();

AuthService:

reauthenticate(authdata: AuthData) {
    this.store.dispatch(UI.StartLoading());
    var credential = firebase.auth.EmailAuthProvider.credential(
      authdata.email,
      authdata.password
    );
    this.afAuth.currentUser.then((user) => {
      user.reauthenticateWithCredential(credential)
        .then((res)=>{
          this.prevPwd = authdata.password;
          console.log(res);
          this.store.dispatch(UI.StopLoading());
        })
        .catch(this.HandleError.bind(this))
    });
  }

And then the above method deleteAccount()

Please suggest.

Daisy
  • 73
  • 1
  • 10

1 Answers1

0

As explained in the doc, this happens because:

delete() is a security-sensitive operation that requires the user to have recently signed in.

The doc also indicates that:

If this requirement isn't met, ask the user to authenticate again and then call firebase.User.reauthenticateWithCredential.

So, you need to handle this specific error and do as indicated by the doc, i.e. "ask the user to authenticate again and then call reauthenticateWithCredential."

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • Hi, I have called `user.reauthenticateWithCredential()` before this method, and only if the user has successfully authenticated themselves, this method is being called. – Daisy Aug 31 '20 at 15:33
  • Please check the post. I have added the entire flow. – Daisy Aug 31 '20 at 15:37
  • If I am not mistaking, I don't see any place in your code where you call `reauthenticateWithCredential()`. – Renaud Tarnec Aug 31 '20 at 15:52
  • Sorry, I just missed adding that part here. it is called from within the `reauthenticate()` method. \n – Daisy Aug 31 '20 at 17:14