firebase-tools-ui icon indicating copy to clipboard operation
firebase-tools-ui copied to clipboard

user reload does not update emailVerified on emulator if emailVerified is updated manually.

Open marcusx2 opened this issue 1 year ago • 7 comments

Operating System

macOS

Browser Version

Safari 16.5.2

Firebase SDK Version

10.7.1

Firebase SDK Product:

Auth

Describe your project's tooling

index.html with source tag. Just javascript.

Describe the problem

emailVerified never returns true when using the emulator after a user.reload and the emailVerified is set to true manually from the console instead of using sendEmailVerification.

I mean to set the emailVerified to true here

image

after creating the user with email and password, instead of sending an email verification with code.

Steps and code to reproduce issue

try {
    const app = initializeApp(firebaseConfig);
    var auth = getAuth();

    connectAuthEmulator(auth, 'http://127.0.0.1:9099');

    var uc = await createUserWithEmailAndPassword(auth, '[email protected]', '123456');
    //at this point, go to emulator console and manually set email to verified
    //instead of sending email verification by code.
    var user = uc.user;
    setInterval(() => {
    if (user?.emailVerified) {
        console.log('email verified');
    } else {
        console.log('email not verified');
        user?.reload();
    }
    }, 0);
} catch (e) {
    console.error(e);
}

marcusx2 avatar Jan 02 '24 21:01 marcusx2

One might think this is not a big deal, but I thought user.reload was simply not working on the emulator after I verified that it works without emulator and wasted a lot of time. If this is not considered a big deal at least I'll leave it documented here.

marcusx2 avatar Jan 02 '24 21:01 marcusx2

Thanks for filing this. Since this issue only happens when using the emulator, I'm going to move this issue to firebase-tools GitHub repository in hopes you can get better support.

NhienLam avatar Jan 08 '24 06:01 NhienLam

Hey @marcusx2, does this issue still occur if you add a call to user = await auth.currentUser();? ie

 if (user?.emailVerified) {
        console.log('email verified');
    } else {
        console.log('email not verified');
        user?.reload();
        user = auth.currentUser()
    }

Based on https://stackoverflow.com/questions/51709733/what-use-case-has-the-reload-function-of-a-firebaseuser-in-flutter, it seems like this is a necessary step.

joehan avatar Jan 09 '24 18:01 joehan

I didn't try that, but it's not a necessary step without the emulator.

marcusx2 avatar Jan 09 '24 20:01 marcusx2

    user?.reload();

Calling user.reload make it work for emulator.

it works without emulator

But it seems it works without it in real device. I wonder if it a necessary step or just emulator bug?

Based on https://stackoverflow.com/questions/51709733/what-use-case-has-the-reload-function-of-a-firebaseuser-in-flutter, it seems like this is a necessary step.

It seems some reliable answer does said it is necessary step.

Calling User.reload() reloads that user's profile data from the server.

user.reload need to be triggered manually after user did verification.

It works without it on real device likely because it fetch from server directly, yet emulator does not?

I think this is need to be documented. I do think it's better if auth listener can trigger it.

readyiman avatar Mar 24 '25 13:03 readyiman

From what I can gather, this seems to be an issue with the Firebase Emulator UI. When user email is updated to verified via the emulator UI, the token becomes invalid and raises an error on the web app

Uncaught (in promise) FirebaseError: Firebase: Error (auth/user-token-expired).

I tried using the Admin SDK to update the user on the Auth emulator, and the web app was able to detect the user email was updated to verified. Similar to production behavior.

The steps were:

  1. Using a web app, run the ff code to create a user:
    try {
      connectAuthEmulator(firebaseAuth, 'http://127.0.0.1:9099');
      var uc = await createUserWithEmailAndPassword(
        firebaseAuth,
        "[email protected]",
        "123456"
      );
      //at this point, go to emulator console and manually set email to verified
      //instead of sending email verification by code.
      var user = uc.user;
      setInterval(() => {
        if (user?.emailVerified) {
          console.log("email verified");
        } else {
          console.log("email not verified");
          user?.reload();
        }
      }, 2500);
    } catch (e) {
      console.error(e);
    }
  1. Update the user email using the Admin SDK
const admin = require('firebase-admin');

process.env.FIREBASE_AUTH_EMULATOR_HOST = "127.0.0.1:9099"
const serviceAccount = require('./service-account.json');

if (!admin.apps.length) {
    admin.initializeApp({
        credential: admin.credential.cert(serviceAccount),
    });
}

async function verifyUserEmail(uid) {
    try {
        const user = await admin.auth().updateUser(uid, {
            emailVerified: true,
        });
        console.log(`Successfully marked user ${uid} as verified.`);
        return user;
    } catch (error) {
        if (error.code === 'auth/user-not-found') {
            console.error(`Error: Could not find user with UID: ${uid}`);
        } else {
            console.error(`An error occurred: ${error}`);
        }
        return null;
    }
}

const userUid = 'LYWzcAAMAcIkuEBgGxi4NYTMK08X'; // Replace with the actual UID of the user

verifyUserEmail(userUid)
    .then(verifiedUser => {
        if (verifiedUser) {
            console.log(`User email is now verified: ${verifiedUser.emailVerified}`);
        }
    })
    .catch(err => {
        console.error('Verification failed:', err);
    });
  1. User is now verified, and the web app console outputs:
email verified

I'll confirm these findings with our engineering team to determine if this should be transferred to the Firebase Emulator UI repository.

aalej avatar Apr 01 '25 17:04 aalej

Transferred this over since it seems like the fix will need to be implemented in this repo.

joehan avatar Apr 01 '25 17:04 joehan