Vue.js

Building A Real-Time Chat Application With Vue.js and Firebase – Part 1


Subscribe On YouTube

DemoCode

Part 1: Setting Up The Project
Part 2: Implementing The Chat Logic
Part 3: Firebase Cloud Functions

Vue.js is a powerful framework for building JavaScript-based single page web-applications and is often considered to combine the best of both, React and Angular.

Firebase is a cloud development platform by Google which offers various services for building modern web & mobile applications. E.g. the Firebase Firestore service enables you to store and sync data in real-time. The Cloud Functions feature enabled you to run mobile back-end code without managing servers.


If you like CodingTheSmartWay, then consider supporting us via Patreon. With your help we’re able to release developer tutorial more often. Thanks a lot!


In this series we’re going to build a real-world chat application by combining the power of Vue.js and Firebase Firestore. Furthermore we’ll also be making use of Firebase Cloud Functions and finally use Firebase Hosting to make our application available to the public.

In this first part of this series we’re going to set up the Vue.js project from scratch, install needed dependencies, establish the connection to Firebase and start implementing the Login component.

Before getting started let’s first take a look at the application we’re going to build in this series.

The final real-time Vue.js chat application will look like the following. Fist the user is able to see a Login screen. To login just enter your name in the text field and click on button Enter Chat or just hit return.

Next the Chat window is opened. If no messages are existing yet the user will see the following result in the browser:

The text No messages yet is printed out and you’re able to enter the first chat message and click on button Submit or hit return to send this message. Next the message is presented in the chat window together with the login name and the time:

All users logged in will be able to see the messages in the chat window. Next you can see the how the output will look like if multiple messages from multiple users are entered:

Finally we’ll be implementing a Cloud Function onMessageCreate which is invoked each time a new message is submitted. This is how the Firebase Cloud Function looks like in the Firebase backend.


The purpose of this method is to monitor the number of message documents already created in Firestore. If more than ten documents are already existing the oldest documents should be deleted, so that only ten messages remain. By using this cloud function we’re able to make sure that the database is not filled with hundreds or thousands of messages.

Creating A New Vue.js 2 Project

Let’s start creating a new Vue.js project by using Vue CLI 3. Therefore you need to make sure that Vue CLI 3 is installed on your system:

$ npm install -g @vue/cli

Having completed the installation of Vue CLI 3 the new command vue is available.

To start creating a new Vue project via the command line just use the vue create command followed by the name of the new project, e.g.:

$ vue create vue-chat

Follow the steps on the command line and create a new project with the following features:

  • Babel
  • Linter / Formatter
  • Router

For detailed instructions take a look at our Getting Started With Vue CLI 3 tutorial.

Now that the Vue.js project is created and configured we’re able to change into the newly created project folder and start the development web server by typing in:

$ npm run serve

The application is then available via http://localhost:8080.

Adding Dependencies

Let’s further complete the project setup by installing needed dependencies.

Adding Bootstrap

Bootstrap is a very popular responsive, mobile-first front-end component library which will be used to build up the user interface of our Angular web application. Let’s install Bootstrap by using the NPM command in the following way:

$ npm install bootstrap jquery popper.js

Then open main.js and insert the following two import statements to include Bootstrap in our project:

import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';

Adding Firebase

Because we’re planning to use various Firebase features we need to add the Firebase JavaScript library to the project as well:

$ npm install firebase

This makes sure that the Firebase JavaScript library is downloaded and installed into the node_modules folder of the project. With that library installed we’re now able to establish a connection to the Firebase service by create a new file src/firebase/init.js and insert the following code:

import firebase from 'firebase/app';
  import firestore from 'firebase/firestore';
  
  // Initialize Firebase
  var config = {
    apiKey: "...",
    authDomain: "...",
    databaseURL: "...",
    projectId: "...",
    storageBucket: "...",
    messagingSenderId: "..."
  };
  const firebaseApp = firebase.initializeApp(config);
  firebaseApp.firestore().settings({ timestampsInSnapshots: true });

  export default firebaseApp.firestore();

The values which are assigned to the properties available in the config object needs to be replaced with the values specific to your Firebase project. To retrieve those settings you need to open the backend of your Firebase account (Firebase console) via URL https://console.firebase.google.com, create a new Firebase project and access the settings in the project settings page via button Add Firebase to your web app.

The Firebase app instance is created by calling method firebase.initializeApp and passing in the config object as a parameter. With the Firebase app instance available we’re now able to access Firestore by calling the firebaseApp.firestore() method. First we’re configuring the Firestore instance by calling the settings method to contain timestamps in snapshots and after that the Firestore instance is being exported, so that we’re able to import it again in our components.

Adding moment.js

Another JavaScript library we’ll be using in our project is Moment.js. Moment.js makes it easy to parse, validate, manipulate, and display dates and times in JavaScript. The following command will install Moment.js:

$ npm install moment

Architecture Of Our Vue.js Chat Application

Before starting to further implement the Vue.js application, let’s first take a look at the architecture of the application:


Here you can see that the application will be split up into three components:

  • Login
  • Chat
  • CreateMessage

Login and Chat are both View Components, which means that those components are connected to a route. The CreateMessage component is used inside Chat component.

The default route of the application is connected to Login component. The component is providing the functionality to output a form, so that the user is able to enter a name and login to the chat.

Having logged into the application the user is automatically redirected to the route which is connected to Chat component, so that the chat view becomes visible. Part of that view is the output of the child component CreateMessage.

Implementation

Implementing Login Component

Now we’re ready to implement the first component of the Vue application: Login component. Create a new file src/view/Login.vue and insert the following code:

<template>
  <div class="container">
    <div class="card login">
      <div class="card-body">
        <h2 class="card-title text-center">Login</h2>
        <form @submit.prevent="login" class="text-center">
          <div class="form-group">
            <input type="text" class="form-control" placeholder="Please enter your name ..." name="name" v-model="name">
            <p v-if="errorText" class="text-danger">{{ errorText }}</p>
          </div>
          <button class="btn btn-primary">Enter Chat</button>
        </form>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: 'home',
  data () {
    return {
      name: "",
      errorText: null
    }
  },
  methods: {
    login() {
      if (this.name) {
        this.$router.push({name: 'Chat', params: {name: this.name}})
      } else {
        this.errorText = "Please enter a name!"
      }
    }
  }
}
</script>

<style>
.login{
  max-width: 450px;
  margin-top: 50px;
  display: block;
  margin-left: auto;
  margin-right: auto;
}
</style>

The template section of this component contains the HTML code which is needed to output a simple Login form. By using this form the user is able to input a name and then submit the form to enter the chat. If the form is submitted without entering a name an error message is output.

The submit event of the form is bound to method login. This functions checks if a name is entered and then uses this.$router.push to redirect to the Chat route (which will be configured later on) and pass over name as a routing parameter.

Routing Configuration

Finally we need to make sure that the routing configuration is in place to load the Login component when the default application path is accessed. Add the following configuration to src/router.js:

  routes: [
    {
      path: '/',
      name: 'Login',
      component: Login
    },
    [...]
  ]

What’s Next

In this first part of the Building A Real-Time Chat Application With Vue.js and Firebase tutorial series we’ve set up the Vue.js project, installed needed dependencies like the Bootstrap framework, established the connection to Firebase and started with the implementation.

In the next part we’re going to further complete the implementation of the Vue application and we’re going to implement the Chat and CreateMessage component.

ONLINE COURSE: Vue.js 2 - The Complete Guide

Check out the great Vue.js online course by Maximilian Schwarzmüller with thousands of students already enrolled:

Vue JS 2 – The Complete Guide 

  • Build amazing Vue.js Applications – all the Way from Small and Simple Ones up to Large Enterprise-level Ones
  • Leverage Vue.js in both Multi- and Single-Page-Applications (MPAs and SPAs)
  • Understand the Theory behind Vue.js and use it in Real Projects

Go To Course


Using and writing about best practices and latest technologies in web design & development is my passion.