DEV Community

WebCraft Notes
WebCraft Notes

Posted on • Originally published at webcraft-notes.com

Building Simple CRM with Vue: Establishing Secure Sign Up Page Using Firebase Authentication

Establishing Secure Sign Up Page Using Firebase Authentication

Check this post in my web notes!

Welcome to the next phase of Vue CRM development, where we delve into the creation of essential components – Login and Sign Up pages. In this tutorial, we'll not only guide you through the process of crafting these crucial user authentication interfaces but also show you how to seamlessly integrate them with Firebase Authentication. By harnessing the power of Firebase Auth, we unlock a realm of benefits for securing user interactions in our Simple CRM. Let's embark on this journey to establish secure Login and Sign Up pages, leveraging the capabilities of Vue.js and Firebase Authentication.

Here is our plan for today's work:

1. Building Auth Layout and Configuring Nested Routes in Vue-Router

2. Designing Sign-Up Page in Vue.js with Vuetify

3. Creating the First Pinia Store

4. Firebase Authentication Integration in Vue CRM

Okay, we have a plan so let's stop talking and start working!

1. Building Auth Layout and Configuring Nested Routes in Vue-Router

Vuetify gives us ready-to-use forms that we can use in our sign-up or login page development, luckily those forms are going with popular validation libraries "Vee-Validate" and "Vuelidate" which simplify our work even more. Also, we can use only inputs and create our forms, I think we will use this variant in building "create products functionality".

So, let's create a new AuthLayout inside the layouts folder and add simple layout styles with a router-view template.

<template>
    <div class="main__content">
        <router-view />
    </div>
</template>
<script>
export default {
    name: 'AuthLayout'
};
</script>
Enter fullscreen mode Exit fullscreen mode

Now, we need to modify our router settings, set additional layouts for auth pages, and add our sign-up page. For that import all pages and components inside the index.js file in the router folder and update routes similar to our MainLayout. The final version of my vue-router file:

import { createRouter, createWebHistory } from 'vue-router';
import MainLayout from '../layouts/MainLayout.vue';
import AuthLayout from '../layouts/AuthLayout.vue';
import SignUp from '../views/SignUp.vue';
import Dashboard from '../views/Dashboard.vue';
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      component: MainLayout,
      children: [
        { 
          path: '', 
          component: Dashboard 
        },
      ],
    },
    {
      path: '/auth',
      component: AuthLayout,
      children: [
        { 
          path: 'sign-up', 
          component: SignUp
        }
      ],
    },
  ]
})
export default router
Enter fullscreen mode Exit fullscreen mode

We can check updates, launch the dev server, and check /auth/sign-up route. We will see an empty sign-up page but it's ok, more important that all our layouts and routes are configured correctly.

2. Designing a Sign-Up Page in Vue.js with Vuetify

Next step, create the SignUpForm component in the components folder and check the forms section in Vuetify documentation. There is a part with a vee-validate example, copy that example and paste it inside the SignUpForm component, do not forget to copy scripts also. Then add some more fields that we would like users to fil them with personal data.

<template>
    <form @submit.prevent="submit">
        <h3 class="mb-5">Sign Up</h3>
        <v-text-field
            v-model="name.value.value"
            :error-messages="name.errorMessage.value"
            label="Name"
        ></v-text-field>
        <v-text-field
            v-model="phone.value.value"
            :error-messages="phone.errorMessage.value"
            label="Phone Number"
        ></v-text-field>
        <v-text-field
            v-model="email.value.value"
            :error-messages="email.errorMessage.value"
            label="E-mail"
        ></v-text-field>
        <v-text-field
            v-model="password.value.value"
            :error-messages="password.errorMessage.value"
            label="Password"
        ></v-text-field>
        <v-text-field
            v-model="repeatPassword.value.value"
            :error-messages="repeatPassword.errorMessage.value"
            label="Repeat Password"
        ></v-text-field>
        <v-btn
            class="me-4"
            type="submit"
        >
            Sign Up
        </v-btn>
        <v-btn 
            color="indigo-darken-3"
            variant="flat">
            Already have an account?
        </v-btn>
    </form>
</template>

<script setup>
  import { ref } from 'vue'
  import { useField, useForm } from 'vee-validate'
  const { handleSubmit, handleReset } = useForm({
    validationSchema: {
      name (value) {
        if (value?.length >= 2) return true
        return 'Name needs to be at least 2 characters.'
      },
      phone (value) {
        if (value?.length > 9 && /[0-9-]+/.test(value)) return true
        return 'Phone number needs to be at least 9 digits.'
      },
      email (value) {
        if (/^[a-z.-]+@[a-z.-]+\.[a-z]+$/i.test(value)) return true
        return 'Must be a valid e-mail.'
      },
      password (value) {
        if (value?.length >= 8) return true
        return 'Password needs to be at least 8 characters.'
      },
      repeatPassword (value) {
        if (value === password.value.value) return true
        return 'Password and Repeat Password values should be equal.'
      },
    },
  })
  const name = useField('name')
  const phone = useField('phone')
  const email = useField('email')
  const password = useField('password')
  const repeatPassword = useField('repeatPassword')
  const submit = handleSubmit(values => {
    console.log('submit');
  })
</script>
Enter fullscreen mode Exit fullscreen mode

And wait a minute, we need to install Vee-Validate into our project, just use "npm i vee-validate".

Great, now import our Form directly inside the SignUp.vue component that we need to create in the views folder, and restart the project.

Once again thank you "UI Verse" for fantastic free UI examples, with their help I added some styles to my sign-up page. Here is the result:
Designing a Sign-Up Page in Vue.js with Vuetify

Looks nice, now we need to implement the Firebase authentication module a save our user in Firebase auth.

3. Creating the First Pinia Store

We will create a new Pinia auth store specially for users. Add a new auth.js file to the store folder, then we need to import the "defineStore" method from pinia and use it for our first store creation.

If you want to learn more about how to work with pinia just check this post.

Next, we will define the state section as an arrow function that will return our user state; an actions object that gonna have methods (like sign-up, log-in...) that we can call from different components of our project; and getters - access to our store state.

import { defineStore } from 'pinia';
export const useAuthStore = defineStore({
    id: 'auth',
    state: () => ({

    }),
    actions: {

    },
    getters: {

    }
});
Enter fullscreen mode Exit fullscreen mode

Now we will add a user variable to our state that will store user data which we will receive from firebase authentication, gUser getter that will give us access to our user state, and finally "aSignUp" method into actions that will call the firebase auth and create new user. Okay, let's go to our next fire step.

4. Firebase Authentication Integration in Vue CRM

First of all visit Firebase Console, click on Authentication module to add it to our project, then choose "Email/Password Sign-in provider" (yes there are many more options but for now we will use only one) enable and save changes.
Firebase Console Auth

The Firebase Authentication module has a "createUserWithEmailAndPassword" method that we gonna use for new user creation.

Open the firebase.js file, import "getAuth" method, use it and export "auth as a result:

import { getAuth } from "firebase/auth";
export const auth = getAuth(app);
Enter fullscreen mode Exit fullscreen mode

Open the auth store file, import the "createUserWithEmailAndPassword" method from "firebase/auth", and also import our "auth" module from the firebase file.

Now, inside the auth store create a new action "aSignUp" method that will call Firebase to create a new user.

All that stuff gonna look something like this:

import { defineStore } from 'pinia';
import { createUserWithEmailAndPassword } from "firebase/auth";
import { auth } from '../firebase/firebase';
export const useAuthStore = defineStore({
    id: 'auth',
    state: () => ({
        user: null
    }),
    actions: {
        async aSignUp(form) {
            try {
                await createUserWithEmailAndPassword(auth, form.email, form.password)
                    .then(async (userCredential) => {
                        this.user = userCredential.user;
                    });
            } catch (error) {
                const errorCode = error.code;
                const errorMessage = error.message;
                console.log(errorCode,errorMessage);
            }
        }
    },
    getters: {
        gUser: (state) => state.user,
    }
});
Enter fullscreen mode Exit fullscreen mode

Awesome! We can create new users now with our Sign-Up form.

Open the SignUpForm component and import the auth store then declare it as a variable. Then modify the handleSubmit function, just call the aSignUp method from the auth store.

import { useAuthStore } from '../../stores/auth';
const authStore = useAuthStore();
const submit = handleSubmit(values => {
    authStore.aSignUp({email: values.email, password: values.password});
})
Enter fullscreen mode Exit fullscreen mode

And inside Firebase Console just check the result:
Firebase result

We did it! Fantastic feelings when everything works as it should. Let's make some small conclusions and move to our next step.

In conclusion, we've successfully laid the foundation for a secure sign-up page in our Vue.js CRM, seamlessly integrating Firebase Authentication for user registration. By utilizing the powerful combination of Vue.js, Vuetify, Pinia, and Firebase, we've created a robust environment for managing user interactions. Stay tuned for further insights as we delve into additional functionalities and continue shaping our Simple CRM.

Top comments (0)