Keith

Vue JS and Firebase Chat Room Application

by Keith Rowles • 03/01/2024Vue

Green and blue manilla folders

Summary

A Vue JS chat application using the composition api, Firebase for the authentication, database and hosting.

This project is using the Vue 3 composition API instead of the options API.

You can register and login to the application.

You can also create and read chats using the realtime listener.

Google Firebase is used for the backend - user authentication, database to store chats and web hosting.

The project has been deployed to Google hosting.

Tech and Tools

  • HTML
  • CSS
  • JavaScript
  • Vue JS
  • Vue Router
  • Google Firebase
  • Vue CLI

Sample Code

welcome.vue

<template>
  <div class="welcome container">
    <div v-if="showLogin">
      <h2>Login</h2>
      <LoginForm @login="enterChat" />
      <p>
        No account yet? <span @click="showLogin = false">Signup</span> instead.
      </p>
    </div>
    <div v-else>
      <h2>Sign up</h2>
      <SignupForm @signup="enterChat" />
      <p>
        Already registered?
        <span @click="showLogin = true">Login</span> instead.
      </p>
    </div>
  </div>
</template>

<script>
  import SignupForm from '@/components/SignupForm.vue';
  import LoginForm from '@/components/LoginForm.vue';
  import { ref } from 'vue';
  import { useRouter } from 'vue-router';

  export default {
    components: { SignupForm, LoginForm },
    setup() {
      const showLogin = ref(true);
      const router = useRouter();

      const enterChat = () => {
        router.push({ name: 'Chatroom' });
      };

      return {
        showLogin,
        enterChat,
      };
    },
  };
</script>

<style>
  .welcome {
    text-align: center;
    padding: 20px 0;
  }
  /* form styles */
  .welcome form {
    width: 300px;
    margin: 20px auto;
  }
  .welcome label {
    display: block;
    margin: 20px 0 10px;
  }
  .welcome input {
    width: 100%;
    padding: 10px;
    border-radius: 20px;
    border: 1px solid #eee;
    outline: none;
    color: #999;
    margin: 10px auto;
  }
  .welcome span {
    font-weight: bold;
    text-decoration: underline;
    cursor: pointer;
  }
  .welcome button {
    margin: 20px auto;
  }
</style>

chatroom.vue

<template>
  <div class="container">
    <Navbar />
    <ChatWindow />
    <NewChatForm />
  </div>
</template>

<script>
  import Navbar from '@/components/Navbar.vue';
  import getUser from '@/composables/getUser';
  import { watch } from 'vue';
  import { useRouter } from 'vue-router';
  import NewChatForm from '@/components/NewChatForm.vue';
  import ChatWindow from '@/components/ChatWindow.vue';

  export default {
    setup() {
      const { user } = getUser();
      const router = useRouter();

      watch(user, () => {
        if (!user.value) {
          router.push({ name: 'Welcome' });
        }
      });

      return { user };
    },
    components: { Navbar, NewChatForm, ChatWindow },
  };
</script>

<style>
  nav {
    padding: 20px;
    border-bottom: 1px solid #eee;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  nav p {
    margin: 2px auto;
    font-size: 16px;
    color: #444;
  }
  nav p.email {
    font-size: 14px;
    color: #999;
  }
</style>

Demo

Open demo on Google hosting.

Link to Demo