Hammam
Hammam

Reputation: 141

firebase: please verify the new email before changing email. (auth/operation-not-allowed)

I was using Firebase authentication by Email/Password on my react-native app and doing emailUpdate through the app successfully , until i decided to move to new Firebase project with the same app changing the Config keys only.

Every thing is working fine I can delete existing email, create a new email , only when I try to updateEmail, I receive the following error :

[firebaseerror: firebase: please verify the new email before changing email. (auth/operation-not-allowed).]

Note: I am not using or requesting any email verification in my code.

Thanks for any support !

Upvotes: 14

Views: 9320

Answers (5)

evdama
evdama

Reputation: 2216

I'm using email link authentication in my app. Now I'm in the process of switching from the deprecated updateEmail() to verifyBeforeUpdateEmail() which entails that the user is signed out in any case as far as I can tell:

At first I thought reauthenticating before calling verifyBeforeUpdateEmail() on the client would avoid that but that doesn't seem to be the case.

The user has to verify his new email by clicking an email link send to him if recently authenticated.

If the last sign in was long ago the user has to verify his current and new email by clicking links send to him to either email addresses.

This is the flow you'll have to deal with when using email link authentication with verifyBeforeUpdateEmail(). In particular, what can happen is this as far as I understood the flow:

  • first because a 'auth/requires-recent-login' error occurs in which case the user has to re-authenticate with his current email i.e. a link is send to his current email address.
  • then immediately after that verifyBeforeUpdateEmail() is being called and no 'auth/requires-recent-login' is raised i.e. the user gets a link send to his new email address and has to click the link at which point the session is terminated by firebase because a major account change happened, email change in this case. At this point the user has verified ownership of the new email address but is signed out by the firebase authentication backend.
  • The client session, as far as I can tell, is unaware of this at this point in time so we need to proactively sign out the user on the client using await signOut(auth) followed by location.reload() at which point the user should be signed out on the client as well and therefore all user state management with e.g. onAuthStateChanged() should do the appropriate thing as well.
  • the user is now signed out on the client and his new email should be active on his account.
  • now the user has to sign in again, just like he did on initial sign up, with his new email address.

That's my learning from the last few days trying to make sense out of this. Please correct me if I'm wrong but given the lack of information out there this is what I figured to be the case.

At first I thought the user wouldn't be required to sign in again because the session wouldn't be terminated but then, changing the email address seems to be a major account change so...

Upvotes: 0

Mudassar Ashraf
Mudassar Ashraf

Reputation: 972

Uncheck email enumeration protection

uncheck Email enumeration protection

Upvotes: 15

Vladimir Deev
Vladimir Deev

Reputation: 389

I had this issue when trying to convert an anonymous user to email and password user. All I did was update firebase to 10.6.0 and it started working as intended. https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection#firebase-console

Upvotes: 0

Chris Thornham
Chris Thornham

Reputation: 69

I was able to get this working by replacing the updateEmail() function with the verifyBeforeUpdateEmail() function.

After verifyBeforeUpdateEmail() is called, firebase sends a confirmation email to the new email address. Once the user clicks the link in the confirmation email, they can sign in with their new email address. You can read more about it in the docs.

Here's a code example that shows the old code and then the new code. My code is written in TypeScript.

// old code
async function firebaseEmailReset(user: User, email: string) {
    try {
        await updateEmail(user, email);
        await signOut(firebaseAuth);
        window.location.reload();
    } catch (error: any) {
        handleFirebaseError(error.message);
    }
}

// new code
async function firebaseEmailReset(user: User, email: string) {
    try {
        await verifyBeforeUpdateEmail(user, email);
        await signOut(firebaseAuth);
        window.location.reload();
    } catch (error: any) {
        handleFirebaseError(error.message);
    }
}

Upvotes: 6

Nobadi
Nobadi

Reputation: 231

I've been emailing with Firebase Support and it seems as though this is, indeed, a bug in the system. However, the representative emailing me provided a temporary workaround, and it works!!

The 'issue' is caused by 'email enumeration', which is now enabled by default as of September 15th, 2023 according to the release notes.

The workaround is to disable email enumeration for your project.

It's a little complicated (pending on your comfort level with command line), but basically you just install Google Cloud SDK (I did it with hombrew). If you do it with home-brew, you can run the commands in any directory, though I ran everything from home directory (not root of project)

brew install --cask google-cloud-sdk

then initialize the project:

gcloud init

Once done, you can simply follow the instructions provided in the link to disable email enumeration for your project, which should solve the problem.

This worked for my iOS projects, but since the solution isn't tied to specific platform, it should work for React Native as well.

I'll post back here once I receive the proper solution to the problem, as from what I can tell the email enumeration is a security feature that could be beneficial to prevent fraud in your app. Until then, I hope this helps!

Upvotes: 7

Related Questions