skip to Main Content

After using createUserWithEmailAndPassword from firebase/auth, Firebase sends a verification email to the user. The verification link successfully verifies the email, but instead of redirecting back to my app, I am redirected to the following URLs:

Local with the emulator:

http://localhost:9099/emulator/auth/handler?apiKey=fake-api-key&appName=%5BDEFAULT%5D&authType=reauthViaRedirect&redirectUrl=http%3A%2F%2Flocalhost%3A3000%2Fapp&v=9.21.0&eventId=VBnwo5RI30cI7UvoCwfBQfZXNmmm%3A%3A%3A7630387099

with the following error:

{ "authEmulator": { "error": "missing apiKey or providerId query parameters" } }

For local emulation on the backend, I am calling admin.auth().generateEmailVerificationLink(email, { url: "http://localhost:3000/app"}) to generate an email verification link. This link looks like:

http://127.0.0.1:9099/emulator/action?mode=verifyEmail&lang=en&oobCode=XXX&apiKey=fake-api-key&continueUrl=http%3A%2F%2Flocalhost%3A3000%2Fapp

It leads to a verification success, then redirects automatically to localhost:3000/app, however it doesn’t stay there long as that is when I am redirected to the error-state URL shown above.

And production:

https://example.com/__/auth/handler?apiKey=XXX&appName=%5BDEFAULT%5D&authType=reauthViaRedirect&redirectUrl=https%3A%2F%2Fexample.com%2Fapp%2Fregister%2Fverify-email&v=9.21.0&eventId=TIaOYg0R5QdkPxrXuZl5IClNFd52%3A%3A%3A9624473175

with the following error:

The requested action is invalid.
...
Request is missing required data

For production, I am letting Firebase handle the verification email by calling sendEmailVerification(auth.currentUser, { url: window.location.href }) on the front end. I do NOT use a custom email action handler [1] [2]. Instead, in the Firebase console, I set the action URL to https://example.com/__/auth/action with the proper domain verification [3], but I’ve also tried it by resetting it to the default, and it causes the same behavior. This is the link it generates:

https://example.com/__/auth/action?mode=verifyEmail&oobCode=XXX&apiKey=XXX&continueUrl=https%3A%2F%example.com%2Fapp%2Fregister%2Fverify-email&lang=en

Additional Details

Note that if I simply navigate a second time to (local) localhost:3000/app or (prod) https://example.com/app, it doesn’t redirect me incorrectly and everything works fine.

Curiously, if I add in &providerId=password to the query parameters, it works just fine; however, I have no idea what is generating this URL nor why it is not including the providerId (if that is even the root of the problem). Any help in understanding what I’m doing wrong?

2

Answers


  1. Chosen as BEST ANSWER

    Answer was resolved here: https://github.com/firebase/firebase-js-sdk/issues/7303

    TL:DR; The issue was calling reauthenticateWithRedirect while attempting to pass the password providerId to the call without providing a credential.

    As soon as the email is verified, the firebase user itself is not authenticated (just the email verified). I thought using reauthenticateWithRedirect would resolve this (and it does, but I need to give it the credential). It looks like for email/password the expectation is supposed to be that the user is forced to sign back in rather than being automatically reauthenticated?

    There doesn't appear to be any way to reauthenticate the password method without having them reenter their credentials. The best bet is to call reauthenticateWithCredential after extracting the email from the firebase user and asking the user to re-enter the password.

    Here's an example:

    const email = auth.currentUser.email;
    const password = ???; // get from user-provided input
    const credential = EmailAuthProvider.credential(email, password);
    await reauthenticateWithCredential(auth.currentUser, credential);
    

    Source


  2. I have recreated the setup from what you have shared and
    According to this thread and the answer provided by Frank

    Verification emails can only be sent from the client-side SDK, and only after the user has signed in. This is done to prevent the ability to abuse Firebase’s servers for sending spam.

    So if you are using admin.auth().generateEmailVerificationLink(email) to send the email verification link to the user then it should be done through SMTP server the templates for that email is registered in your Firebase Console’s Authentication Templates Tab.

    I will recommend you to send the email verification link from the Client SDK when the user is created using Send a user a verification email and to make your user return to your app. And make sure to add ActionCodeSettings url which helps your users to return to your App.

    Now Regarding the Error you got :
    http://localhost:9099/emulator/auth/handler is what the client SDK will redirect to, but requires the client SDK in order to work
    If you want to redirect the user to your app then you will need to add the redirect url inside the ActionCodeSettings.

    Update :
    If your app’s homepage is http://localhost:3000/app then it should redirect you to there. But the url field of actionCodeSettings could have different meanings in the different context as per the docs :

    (property) ActionCodeSettings.url: string
    
    Sets the link continue/state URL.
    
    @remarks
    This has different meanings in different contexts:
    
    1. When the link is handled in the web action widgets, this is the deep link in the continueUrl query parameter.
    2. When the link is handled in the app directly, this is the continueUrl query parameter in the deep link of the Dynamic Link.
    

    Your issue falls under 1st category so double check the url.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search