check if the email is real one before signup in firebase

Viewed 1434

am working on a little project and i did finish all the authentication work but one thing,am wondering how to check if the email is real before going into the process of signup, by the way am using react and Firebase and i did look online and i did find a package called email-existence i did try it and it dose return true if the email is real and false if the email dosent exist but thats not working when i use it with react it return an error

import firebase from '../util/firebase';
const emailExistence = require('email-existence');

export const normalSignup = (props, setSign, email, password, confirmPassword, username) => {
  emailExistence.check(email, function (error, response) { // return error here addresses.sort is not a function
    console.log('res: ' + response);
  });
}

anyway am wondering if there's a way to do it with Firebase without external packages thanx in advance PS:am not using cloud functions

3 Answers

Well assuming you want to check if the email is a verified email address you can write the code in the following way

import firebase from '../util/firebase';
const App = {
  firebase: firebase,
  getLoggedInUser: () => {
    const currentUser = App.firebase.auth().currentUser
    if (currentUser) {
      return {
        email: currentUser.email,
        userId: currentUser.uid,
        isEmailVerified: currentUser.emailVerified
      }
    } else {
      return undefined
    }
  },
  isAuthenticated: () => {
    return (App.getLoggedInUser() && App.getLoggedInUser().isEmailVerified)
  },
  authenticate: async (email, password) => {
    await App.firebase.auth().signInWithEmailAndPassword(email, password)
  },
  signup: async (email, password) => {
    const userCredential = await App.firebase.auth().createUserWithEmailAndPassword(email, password)
    await userCredential.user.sendEmailVerification()
    return `Check your email for verification mail before logging in`
  },

Here the following happens

  • When a user signs up the signup method is called and an email verification is sent by firebase as shown in the above code
  • When a user logs in the authenticate method is called so according to firebase you are logged in
  • However to redirect or render a certain page say after log in you can use the isAuthenticated method to display a page to a certain user
  • So you can pass method isAuthenticated as a prop to react-router and render your web application how you want.
  • This way only real and authentic email id which are verified will have access to your app

Note

This method is working already in prod but its using VueJS and is an opensource project on github let me know if you want to reference it

Maybe just use a regex to check if the email is valid?

According to this webpage for JavaScript you just need:

const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

if (emailRegex.test(email)) {
    console.log('Email valid!');
}

This won't stop people entering emails for incorrect domains, but ensures that if someone uses a mail server that isn't widely known, it will get accepted too.

Your only option on the client side (if you are on Firebase I suppose you don't have the luxury to run a Node backend) to fetch a similar service as email-existence which returns a "valid" or "invalid" response if you GET the endpoint with the email address.

These are usually premium services, but if you have low traffic you can try out a free one. In my example it is Mailboxlayer. Their endpoint can be called like this (and of course if you are stick to the client side it means anyone can steal your api key from production via browser network tab!):

GET http://apilayer.net/api/check?access_key=YOUR_ACCESS_KEY&email=richard@example.com

Which returns a JSON:

{
  "email": "richard@example.com",
  "did_you_mean": "",
  "user": "support",
  "domain": "apilayer.net",
  "format_valid": true,
  "mx_found": true,
  "smtp_check": true,
  "catch_all": false,
  "role": true,
  "disposable": false,
  "free": false,
  "score": 0.8
}   

Best to use score, which:

[...] returns a numeric score between 0 and 1 reflecting the quality and deliverability of the requested email address.

In React:

  const [data, setData] = useState(null)
  const [emailToVerify, setEmailToVerify] = useState('richard@example.com') // just for the sake of example
  const apiKey = process.env.API_KEY

  const fetchEmailVerificationApi = useCallback(async () => {
    try {
      const response = await fetch(`http://apilayer.net/api/check?access_key=${apiKey}&email=${emailToVerify}`)
      const json = await response.json()
      setData(json.score) // returns a numeric score between 0 and 1 reflecting the quality and deliverability of the requested email address.
    } catch (e) {
      console.error(e)
    }
  }, [apiKey, emailToVerify])

  useEffect(() => {
    fetchEmailVerificationApi()
  }, [fetchEmailVerificationApi])
Related