Wednesday, 31 August 2022

How to verify that the email is authentic in Firebase?

I need to add to my current code, the necessary functionality and the exact code so that the user must verify the email before logging in.

Now, the user registers and automatically accesses all the functions of the application and its user panel. I want to add the necessary function so that when a user registers, a message is shown telling him that: You must verify your email In this way we ensure that it is a valid email and avoid the registration of SPA users.

I need the user to verify her email to be able to log in, until she does, she can continue using the App as she did, without logging in.

You can see that I did several tests, and other users tried to help me, but we have not achieved what is necessary, since I need to add the functionality to the code that I have now, since it is the only way I know to continue building my application.

The app has registration with Firebase, registered by email and password and I'm using Formik to control the state of the form and Yup to validate.

I have read Firebase documentation about "Send a verification message to a user",

This is the Firebase function:

```
const auth = getAuth();
sendEmailVerification(auth.currentUser)
  .then(() => {
    // Email verification sent!
    // ...
  })
```

The registration system I use now is Mail and Password. The user enters an email, a password, verifies the password and is automatically registered in the application.

I did several tests trying to add sendEmailVerification to my registration system, and for now what I have achieved is that the confirmation email arrives to the user (SPA folder) but the confirmation email arrives after the user already registered and use the app.

It would be necessary that the user could not register until receiving and confirming the "Confirmation Email"

I need a code example that fits my current app, I don't have the knowledge to change all my code, this is the base of my app.

What do I have to do so that this works correctly and the verification email arrives before the user can register? What am I doing wrong in my code?

You can test the project as it is built with Expo:

exp://exp.host/@miguelitolaparra/restaurantes-5-estrellas?release-channel=default

enter image description here

This is the method I'm using to register users:

const formik = useFormik({
    initialValues: initialValues(),
    validationSchema: validationSchema(), // validate the form data
    validateOnChange: false,
    onSubmit: async(formValue) => {
      try { // send the data to Firebase
        const auth = getAuth()
       // sendEmailVerification(auth.currentUser)
        await createUserWithEmailAndPassword(
          auth,
          formValue.email,
          formValue.password
        )
      
       sendEmailVerification(auth.currentUser)

        navigation.navigate(screen.account.account)
      } catch (error) {
        // We use Toast to display errors to the user
        Toast.show({
          type: "error",
          position: "bottom",
          text1: "Failed to register, please try again later",
        })
      }
    },
  })

And I also show you the complete file:

import { useFormik } from 'formik'
import { getAuth, createUserWithEmailAndPassword, sendEmailVerification } from 'firebase/auth'

export function RegisterForm() {
  const [showPassword, setShowPassword] = useState(false)
  const [showRepeatPassword, setShowRepeatPassword] = useState(false)

  const navigation = useNavigation()

  const formik = useFormik({
    initialValues: initialValues(),
    validationSchema: validationSchema(), // validate the form data
    validateOnChange: false,
    onSubmit: async (formValue) => {
      try { // send the data to Firebase
        const auth = getAuth()
        //sendEmailVerification(auth.currentUser)
        await createUserWithEmailAndPassword(
          auth,
          formValue.email,
          formValue.password
        )
      sendEmailVerification(auth.currentUser)

       
        navigation.navigate(screen.account.account)
      } catch (error) {
        // We use Toast to display errors to the user
        Toast.show({
          type: "error",
          position: "bottom",
          text1: "Error al registrarse, intentelo mas tarde",
        })
      }
    },
  })

  // function to hide or show the password
  const showHidenPassword = () => setShowPassword((prevState) => !prevState)
  const showHidenRepeatPassword = () => setShowRepeatPassword((prevState) => !prevState)

  return (
    // Registration form interface
    <View>
      <Input
        placeholder="Correo electronico"
        keyboardType="email-address"
        containerStyle={AuthStyles.input}
        rightIcon={
          <Icon type="material-community" name="at" iconStyle={AuthStyles.icon} />
        }
        onChangeText={(text) => formik.setFieldValue("email", text)}
        errorMessage={formik.errors.email}
      />
      <Input
        placeholder="Contraseña"
        containerStyle={AuthStyles.input}
        secureTextEntry={showPassword ? false : true}
        rightIcon={
          <Icon
            type="material-community"
            name={showPassword ? "eye-off-outline" : "eye-outline"}
            iconStyle={AuthStyles.icon}
            onPress={showHidenPassword}
          />
        }
        onChangeText={(text) => formik.setFieldValue("password", text)}
        errorMessage={formik.errors.password}
      />
      <Input
        placeholder="Repetir contraseña"
        containerStyle={AuthStyles.input}
        secureTextEntry={showRepeatPassword ? false : true}
        rightIcon={
          <Icon
            type="material-community"
            name={showRepeatPassword ? "eye-off-outline" : "eye-outline"}
            iconStyle={AuthStyles.icon}
            onPress={showHidenRepeatPassword}
          />
        }
        onChangeText={(text) => formik.setFieldValue("repeatPassword", text)}
        errorMessage={formik.errors.repeatPassword}
      />
      <Button
        title="REGISTRATE"
        containerStyle={AuthStyles.btnContainer}
        buttonStyle={AuthStyles.btn}
        onPress={formik.handleSubmit} // send the form
        loading={formik.isSubmitting}// show loading while doing user registration
      />
    </View>
  )
}

And this is the file to validate the form with Yup RegistreFormValidar.js

import * as Yup from "yup"

// object that has the elements of the form
export function initialValues() {
  return {
    email: "",
    password: "",
    repeatPassword: "",
  }
}

// validate the form data whit Yup
export function validationSchema() {
  return Yup.object({
    email: Yup.string()
      .email("El email no es correcto")
      .required("El email es obligatorio"),
    password: Yup.string().required("La contraseña es obligatoria"),
  
    repeatPassword: Yup.string()  // validate that the passwords are the same
      .required("La contraseña es obligatoria")
      .oneOf([Yup.ref("password")], "Las contraseñas tienen que ser iguales"),
  })
}


from How to verify that the email is authentic in Firebase?

No comments:

Post a Comment