firebase admin SDK create user and send verification email
Asked Answered
B

8

21

How can I send a verification email after I create a user with firebase admin SDK? I am trying to combine createUser function and sendEmailVerification function could somebody indicate a hint or an answer? thanks

update:

the user creation is being done by an admin user who is already signed in in the app, so the admin user is just creating users on the dashboad. This is completely different from the registeration methods.

update 2:

I tried to follow bojeil's answer, I am still stuck with the step that user signs in with the custom token. It gets into conflict with my current admin user session, the admin users gets kicked out and instead the new user is signed in and even when I sign out the new user, the admin user is still out and needs to sign in to get back into the app.

here is my code inside the app after I get the custom token:

$http.post('/.custom-token', {uid: $scope.data.data.uid})
        .then(function (response) {
            console.log("custom token here:", response.data.token);
            firebase.auth().signInWithCustomToken(response.data.token)
                .then(function (firebaseUser) {
                    firebaseUser.sendEmailVerification();
                    firebase.auth().signOut().then(function() {
                        // Sign-out successful.
                        console.log("signed out success");
                    }, function(error) {
                        // An error happened.
                    });
                })

                .catch(function(error) {
                    // Handle Errors here.
                    var errorCode = error.code;
                    var errorMessage = error.message;
                    // ...
                });

        });

so, I get the token, sign in the new user, send the email verification link, and then, sign out the new user. But my admin user who is doing all of this gets signed out as well. what am I missing here?

Bludge answered 26/1, 2017 at 20:42 Comment(2)
Hi! I am looking into something similar. How did you overcome the admin logging out - problem?Hesper
you should call the signOut function in the then function of the sendEmailVerification(). Since sendEmailVerification is async, you should wait until the execution is completed and then call the signOut function.Bulk
I
22

OK this is what you can do but you may hit quota limitations:

  • Include the firebase-admin module.
  • Include the firebase client module.
  • using admin sdk, create the new user via createUser
  • when that promise resolves, get the uid of the user created.
  • using admin sdk, create custom token for that uid.
  • using client sdk, signInWithCustom token using that custom token.
  • A user is returned in the process, call user.sendEmailVerification()
  • signOut that user from the client SDK.
Inordinate answered 27/1, 2017 at 1:58 Comment(6)
hmmm, but signing in with the user token, will it be in conflict with my current admin user signed-in session?Bludge
The user sign in will not conflict with your admin session. You cannot rely on currentUser in this case and run your sendEmailVerification on the returned user instance on sign in.Inordinate
thanks for the hints, i tried to follow your explanation but i still have problem, please see my updated question. thanks.Bludge
I don't think I understand what you mean by admin user? Here is one thing you can do, you can create a copy of a firebaseApp where you run these temp sign in operations: var tempApp = firebase.initializeApp(clientConfig, 'temp'); You then use tempApp.auth().signInWithCustomToken... This wouldn't conflict with your other instance.Inordinate
I spent several days on this issue, and found this answer. Thanks for the answer. You made my day :)Longhorn
How do you "sign out that user from the client SDK" without also signing out the admin user? As an admin, I create a new user but then that last line signs out the new user and me (the admin user).Patinous
R
6

A rather clean solution would be to actually use the REST APIs.

curl 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/getOobConfirmationCode?key=[API_KEY]' \
-H 'Content-Type: application/json' \
--data-binary '{"requestType":"PASSWORD_RESET","email":"[[email protected]]"}'

The [API KEY] is a web client api key that can be retrieved from Project Settings > add an app >> click web and you will get the configuration with a JSON, within the JSON there is an APIKey that is the one that you need to use.

Recoup answered 4/10, 2018 at 4:55 Comment(0)
A
5

According to firebase, the admin-sdk does not currently support this feature. See their response here: https://mcmap.net/q/621114/-is-there-a-way-to-send-the-verification-email-with-the-firebase-admin-sdk-from-my-node-js-server

Whenever an email / password authentication user is logged in, and attempts to use a feature that requires authentication, I call onAuthStateChanged() and then check the user's record for email verification.

If the email is not verified, and I have not sent a verification email before, I send it automatically. I return an error, asking the user to verify their email. (I store a variable in a profile setup for the user in firestore, to indicate whether it has been sent previously).

On future attempts to use the app, if the email is still not verified, I return the same error, and also include a button in the error labeled "re-send verification email" that triggers sending of the verification email when pressed. (This way I am not automatically sending tons of verification emails every time the user tries to do something.)

Apc answered 27/2, 2018 at 17:4 Comment(0)
L
3

Here's bojeil's steps in code, which work in a NodeJS Firebase Cloud Function. Assuming that 'admin' is your Firebase Admin SDK instance, and 'firebase' is your Firebase Client SDK instance.

var userId = "YOURUSERIDHERE";
admin.auth()
        .createCustomToken(userId)
        .then((customToken) => {
            return firebase.auth().signInWithCustomToken(customToken)
        })
        .then((data) => {
            return data.user.sendEmailVerification({url: "http://YOURREDIRECTURL"});
        }).then((result) => {
            console.log("success");
        }).catch((error) => {
            console.log("faillure");
        });

Make sure that you've setup the Admin SDK properly, by creating a service account and initialising it in the Admin SDK configuration snippet.

Lymn answered 5/2, 2022 at 23:4 Comment(0)
T
2

You don't even need to use the Firebase Admin SDK for this. You can just use the regular Firebase client-side SDK:

firebase.auth().createUserWithEmailAndPassword(email, password)
  .then(function(user) {
     console.log("User successfully created:", user.uid);
     return user.sendEmailVerification();
  })
  .then(function() {
    console.log("Email verification email successfully sent!");
  })
  .catch(function(error) {
    console.log("Error:", error);
  });
Twibill answered 26/1, 2017 at 23:14 Comment(3)
i think you are missing the point: If the new account was created, the user is signed in automatically. Have a look at the Next steps section below to get the signed in user details. it is automatically signed in. The user who is creating another userX is already signed in, if this new userX also gets signed in, there will be a conflict in the session tokens.Bludge
I unfortunately don't understand what you are trying to ask for.Twibill
That worked for me. I had to adjust slightly the first callback (user)=>user.user.sendEmailVerification()Willowwillowy
V
2

I think we can try the following combinations:

Villus answered 19/10, 2021 at 7:15 Comment(0)
Q
1

What I did is very simple:

  1. Create a user in the server
  2. In the client await the server creation and after that sign-in using the client SDK,
  3. in the background listening to firebase auth user change event and than use the user and call sendEmailVerification

This is my React code:

 await Api('signupUser', data) // server call

 await firebase
        .auth()
        .signInWithEmailAndPassword(email, password); //client login

 // send email on login
 useEffect(() => {
      return firebase.auth().onIdTokenChanged((user) => 
      user?.sendEmailVerification());
  }, []);
Quitrent answered 17/10, 2022 at 21:40 Comment(0)
C
0

2023

The accepted answer and some other ones are already old now. There is now a function generateEmailVerificationLink that can generate the verification link for any persisted user.

Generate the verification link and send it, for example, using Nodemailer (I recommed this way, it's simple) or some 3rd party mail API.

Celinacelinda answered 30/7, 2023 at 12:36 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.