0

I've created a rest API for signup. The idea is to create the user using

admin.auth().createUser({...}) method and after getting the response send an email confirmation link to the email provided by the user.

Another thing that needs to be done is to create a collection called 'users' and add some user data to a document which will have the id equals to auth id.

Problem is my application is creating users just fine but I'm not getting any email confirmations nor the data is getting added to the collection.

CODE:

const functions = require("firebase-functions");
const admin =  require("firebase-admin");
const express = require("express");
const app = express();
const cors = require("cors")({origin: true});

admin.initializeApp();
const db = admin.firestore();


app.get("/hello-world", (req, res) => {
    res.send("Hello World!");
});


// create user with email and password with admin sdk
app.post("/signup", cors, (req, res) => {
    const email = req.body.email;
    const password = req.body.password;
    
    // check if email is a valid email
    if (!email || !email.match(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i)) {
        res.status(400).send("Invalid email");
        return;
    }
    
    admin.auth().createUser({
        email: email,
        password: password,
        emailVerified: false,
    }).then(function(userRecord) {
        admin.auth().sendEmailVerification(userRecord.uid).then(function() {
            res.send("User created");
        })
        return db.collection("users").doc(userRecord.uid).set({
            email: userRecord.email,
            password: userRecord.password,
            emailVerified: userRecord.emailVerified,
            username: "",
            firstName: "",
            lastName: "",
        });
    }).then(null, function(error) {
        res.status(400).send(error);
    })
});


exports.app = functions.https.onRequest(app);
Gourav B
  • 864
  • 5
  • 17

1 Answers1

0

The Admin SDK has no sendEmailVerification method. Although it has generateEmailVerificationLink() which can be used to generate a verification link, you would have to send the email yourself. You can try using Nodemailer or Firestore Trigger Email extension. Also the return statement would run before the email function so try handling the promises correctly. You can try using an async function as shown:

app.post("/signup", cors, async (req, res) => {
  const email = req.body.email;
  const password = req.body.password;

  // check if email is a valid email
  if (!email || !email.match(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i)) {
    res.status(400).send("Invalid email");
    return;
  }

  const userRecord = await admin.auth().createUser({
    email: email,
    password: password,
    emailVerified: false,
  })
  // Custom function to generate link and send email
  // await sendVerificationEmail()
  await db.collection("users").doc(userRecord.uid).set({
    email: userRecord.email,
    password: userRecord.password,
    emailVerified: userRecord.emailVerified,
    username: "",
    firstName: "",
    lastName: "",
  });
  return res.sendStatus(200)
});

Other option would be to sign in users on client after /signup is completed and use sendVerificationEmail function using the client SDK.

Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
  • Alright so the gist is that only client sdk has `sendVerificationEmail` option right? So if I try to send confirmation email via backend I'll have to do it custom. My other question is. Since we're defining the `emailVerified: false` right? So does the verification makes it true or do I have to do something? –  Aug 16 '21 at 06:17
  • @FahimHoque not totally custom. `generateEmailVerificationLink` will give you the link but you would have to email that manually yourself. Rest procedure should remain the same. – Dharmaraj Aug 16 '21 at 06:20
  • Hi, sorry for the late reply. I ended up using the client sdk for email confirmation. Is there any way to make the `emailVerified` attribute true after the user confirms the email? –  Aug 17 '21 at 10:12
  • @FahimHoque Firebase does that for you once the user verified themselves by clicking the link. Although I'm not sure if you need to force refresh user's id token – Dharmaraj Aug 17 '21 at 10:13