In this Vue.js tutorial, we will use the existing Google Firebase Javascript SDK that can access the Firebase Realtime-database. Previously, we have created a Vue.js Firebase tutorial CRUD web app which is a simple CRUD operation to populate Firebase Firestore Data.
The flow of this Vue.js Firebase chat web app is very simple.
For more clear explanation, you can refer to this sequence diagram.
The following tools, framework, and module are required for this tutorial:
We assume that you have already installed Node.js. Make sure Node.js command line is working (on Windows) or runnable in Linux/OS X terminal.
Next, we will set up or create a new Google Firebase project that can use the realtime database. Just open your browser then go to Google Firebase Console and you will take to this page.
From that page, click “+” add project button to create a Google Firebase project then it will be redirected to this page.
After filling the project name text field which our project name is “vue-chat-app” then click continue button and it will be redirected to this page.
This time, choose to not add Firebase analytics for now then click Create Project button.
Now, you have a Google Firebase Project ready to use.
After click Continue button it will be redirected to this page.
While develope menu expanded in the left menu, choose “Create Database” then it will open this dialog.
Select “Start in test mode” then click next and it will go to the next dialog.
Select the Firebase database server location (better near you Angular server location) then click Done button. Don’t forget to select or change Cloud Firestore to Realtime Database in Develop -> Database dashboard. Next, go to the Rules tab and you will see these rules values.
{
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
"rules": {
".read": false,
".write": false
}
}
Change it to readable and writeable from everywhere for this tutorial only.
{
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
"rules": {
".read": "auth === null",
".write": "auth === null"
}
}
Click the publish button to update or save the changes. Now, the Google Firebase database is ready to use with your Vue.js chat web app.
Vue-CLI is standard tooling Vue.js development. It has the features out-of-the-box support for Babel, TypeScript, ESLint, PostCSS, PWA, Unit Testing & End-to-end testing, fully configurable without the need for ejecting, allows the community to build and share reusable solutions to common needs, create, develop and manage your projects through an accompanying graphical user interface, and instantly prototype new ideas with a single Vue file. To install Vue-CLI 3 type this command from the Terminal or Node command line.
sudo npm install -g @vue/cli
or
yarn global add @vue/cli
Next, check the version to make sure that you have the 3.x version of Vue-CLI.
vue --version
3.11.0
Next, create a new Vue.js project with the name “vue-firebase-chat” by type this command.
vue create vue-firebase-chat
For now, use the default for every question that shows up in the Terminal. Next, go to the newly created folder.
cd ./vue-firebase-chat
To make sure that created Vue.js project working, type this command to run the Vue.js application.
npm run serve
or
yarn serve
You will see this page when open [http://localhost:8080/
](http://localhost:8080/ "http://localhost:8080/
") in the browser.
We will use Firebase Javascript SDK that available as a Node module. For that, type this command to install the Firebase module after stop the running Vue.js app (press ctrl + c).
npm install --save firebase
Next, create a new file Firebase.js
in the root of the project folder for Firebase configuration.
touch src/Firebase.js
Open and edit src/Firebase.js
then add these imports of Firebase SDK module.
import * as firebase from 'firebase';
Add the constant variables of settings and Firebase configuration parameters after the imports declarations.
const config = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
databaseURL: "YOUR_DATABASE_URL",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET"
};
Initialize Firebase configuration settings.
firebase.initializeApp(config);
Export this file as a module by adding this line at the end.
export default firebase;
You can find or get those configuration parameters by click on the settings (gear button) -> Project Settings to get web API key and Project ID. Click Develop -> Authentication then scrolls to Authorized domain to get authDomain value. In order to get the value of storageBucket, you have to enable or start a Storage by going to Develop -> Storage.
As you see in the sequence diagram before the steps, we need to navigate through the required pages. So, we will create those pages manually by creating the files and folder for them.
touch src/components/Chat.vue
touch src/components/Room.vue
touch src/components/AddRoom.vue
touch src/components/Login.vue
Next, install “vue-router” using Vue-CLI.
vue add router
Leave the question as default then finished the router installation. That Vue-CLI command added a new view folder that contains home and about also added a router.js file that contains the routing for that views and components. In our case, the home and about the view is not necessary, so we have to open and edit router.js
then replace the imports to these imports.
import Vue from 'vue'
import Router from 'vue-router'
import Chat from './components/Chat.vue'
import Room from './components/Room.vue'
import AddRoom from './components/AddRoom.vue'
import Login from './components/Login.vue'
Change the generated routes array to accommodate the last created components.
routes: [
{
path: '/chat/:nickname/:roomid/:roomname',
name: 'Chat',
component: Chat
},
{
path: '/room/:nickname',
name: 'RoomList',
component: Room
},
{
path: '/add-room',
name: 'AddRoom',
component: AddRoom
},
{
path: '/',
name: 'Login',
component: Login
}
]
Next, remove unwanted elements from the main view by open and edit src/App.vue
then make the Vue.js template like this.
<template>
<div id="app">
<router-view/>
</div>
</template>
We will Bootstrap-Vue for the theme or styling the UI of the Chat Room. Using BootstrapVue we can build responsive, mobile-first projects on the web using Vue.js and the world’s most popular front-end CSS library Bootstrap v4. Type this Vue-CLI command to install the bootstrap-vue module.
vue add bootstrap-vue
Next, open and edit src/components/Login.vue
then add the required template that contain , , , , , , and .
<template>
<b-row>
<b-col cols="12">
<h2>
Login
</h2>
<b-jumbotron>
<b-form @submit="onSubmit">
<b-form-group>
<b-form-input id="nickname" v-model.trim="login.nickname" placeholder="Enter your nickname"></b-form-input>
</b-form-group>
<b-button type="submit" variant="primary" :disabled="!login.nickname">Login</b-button>
</b-form>
</b-jumbotron>
</b-col>
</b-row>
Add the Vue script that contains login objects and a method to submit login to redirect to Room List page with a nickname parameter.
<script>
import router from '../router'
export default {
name: 'AddBoard',
data () {
return {
login: { nickname: '' }
}
},
methods: {
onSubmit (evt) {
evt.preventDefault()
router.push({
name: 'RoomList',
params: { nickname: this.login.nickname }
})
}
}
}
</script>
Add a little style to clean up the view.
<style>
.jumbotron {
padding: 2rem;
}
</style>
After login it will redirected to the room list. For that, open and edit src/components/Room.vue
then add these bootstrap-vue template that contain , , for redirect to Add Room Page, , and with iteration of room array.
<template>
<b-row>
<b-col cols="12">
<h2>
Room List
<b-link href="/add-room">(Add Room)</b-link>
</h2>
<b-list-group>
<b-list-group-item v-for="room in rooms" :key="room.key" :to="{name: 'Chat', params: {nickname: nickname, roomid: room.key, roomname: room.roomName}}" action>
{{room.roomName}}
</b-list-group-item>
</b-list-group>
</b-col>
</b-row>
</template>
Add the Vue.js script that contains data of nickname, room array, error array, Firebase realtime-database reference to chatrooms document, and a method to load or get the list of room from the Firebase Realtime-Database.
<script>
import firebase from '../Firebase'
export default {
name: 'BoardList',
data () {
return {
nickname: this.$route.params.nickname,
rooms: [],
errors: [],
ref: firebase.database().ref('chatrooms/')
}
},
created () {
this.ref.on('value', (snapshot) => {
this.rooms = [];
snapshot.forEach((doc) => {
let item = doc.val()
item.key = doc.key
this.rooms.push(item)
});
});
}
}
</script>
Add a little style to clean up the view.
<style>
.table {
width: 96%;
margin: 0 auto;
}
</style>
Next, open and edit src/components/AddRoom.vue
then add the Bootstrap-Vue template that contains the required Bootstrap-vue and other components to submit a new room.
<template>
<b-row>
<b-col cols="12">
<h2>
Add Room
<b-link @click="$router.go(-1)">(Room List)</b-link>
</h2>
<b-jumbotron>
<b-form @submit="onSubmit">
<b-form-group>
<b-form-input id="roomname" v-model.trim="room.roomName" placeholder="Enter Room Name"></b-form-input>
</b-form-group>
<b-button type="submit" variant="primary" :disabled="!room.roomName">Save</b-button>
</b-form>
</b-jumbotron>
</b-col>
</b-row>
</template>
Add a Vue.js script that contains Firebase realtime-database reference to chatrooms, room object, and a method to submit a new room to the Firebase realtime-database then redirect back to the Room List page.
<script>
import firebase from '../Firebase'
import router from '../router'
export default {
name: 'AddBoard',
data () {
return {
ref: firebase.database().ref('chatrooms/'),
room: { roomName: '' }
}
},
methods: {
onSubmit (evt) {
evt.preventDefault()
let newData = this.ref.push()
newData.set({
roomName: this.room.roomName
})
router.go(-1)
.catch((error) => {
alert("Error adding document: ", error)
});
}
}
}
</script>
Add a little style to adjust the view.
<style>
.jumbotron {
padding: 2rem;
}
</style>
Now, we will be working on the main feature of this tutorial, that is Bootstrap-vue chat page. But first, we have to install vue-chat-scroll because we want the chat conversation always scroll to the last chat message. Type this command to install it.
yarn add vue-chat-scroll --save
or
npm install -save vue-chat-scroll
Next, open and edit src/main.js
then add this import.
import VueChatScroll from 'vue-chat-scroll'
Register that VueChatScroll module after the Vue config.
Vue.use(VueChatScroll)
Next, open and edit src/components/Chat.vue
then add the Bootstrap-vue template that contains the list of chat messages that iterated from the chats array, exit chat link, and the send message form.
<template>
<b-row>
<b-col cols="12">
<h2>
{{roomname}}
<b-link @click="exitChat()">(Exit Chat)</b-link>
</h2>
<div class="chat-box" v-chat-scroll>
<b-list-group>
<b-list-group-item class="chat-item" v-for="chat in chats" :key="chat.key">
<div class="chat-status text-center" v-if="chat.type==='join'||chat.type==='exit'">
<span class="chat-date">{{chat.sendDate}}</span>
<span class="chat-content-center">{{chat.message}}</span>
</div>
<div v-else>
<div class="chat-message text-right" v-if="chat.user === nickname">
<div class="right-bubble">
<span class="msg-name">Me</span>
<span class="msg-date">{{chat.sendDate}}</span>
<p text-wrap>{{chat.message}}</p>
</div>
</div>
<div class="chat-message text-left" text-left v-if="chat.user !== nickname">
<div class="left-bubble">
<span class="msg-name">{{chat.user}}</span>
<span class="msg-date">{{chat.sendDate}}</span>
<p text-wrap>{{chat.message}}</p>
</div>
</div>
</div>
</b-list-group-item>
</b-list-group>
</div>
<footer class="sticky-footer">
<b-form @submit="onSubmit">
<b-input-group>
<b-form-input id="message" v-model.trim="data.message" placeholder="Enter your message"></b-form-input>
<b-button type="submit" variant="primary" :disabled="!data.message">Send</b-button>
</b-input-group>
</b-form>
</footer>
</b-col>
</b-row>
</template>
Automatic vue-chat-scroll implemented in the div before the list of the chat message. Next, add the Vue.js script that contains the Firebase realtime-database reference to the chats collections, required variables, array, objects, and the method to submit a new message to the Firebase realtime-database and exit chat while submitting data to Firebase.
<script>
import firebase from '../Firebase'
import router from '../router'
export default {
name: 'Chat',
data () {
return {
roomid: this.$route.params.roomid,
roomname: this.$route.params.roomname,
nickname: this.$route.params.nickname,
data: { type:'', nickname:'', message:'' },
chats: [],
errors: [],
offStatus: false
}
},
created () {
let joinData = firebase.database().ref('chatrooms/'+this.roomid+'/chats').push();
joinData.set({
type: 'join',
user: this.nickname,
message: this.nickname+' has joined this room.',
sendDate: Date()
});
this.data.message = '';
firebase.database().ref('chatrooms/'+this.roomid+'/chats').on('value', (snapshot) => {
this.chats = [];
snapshot.forEach((doc) => {
let item = doc.val()
item.key = doc.key
this.chats.push(item)
});
});
},
methods: {
onSubmit (evt) {
evt.preventDefault()
let newData = firebase.database().ref('chatrooms/'+this.roomid+'/chats').push();
newData.set({
type: 'newmsg',
user: this.nickname,
message: this.data.message,
sendDate: Date()
});
this.data.message = '';
},
exitChat () {
let exitData = firebase.database().ref('chatrooms/'+this.roomid+'/chats').push()
exitData.set({
type: 'exit',
user: this.nickname,
message: this.nickname+' has exited this room.',
sendDate: Date()
})
this.offStatus = true
router.go(-1)
}
}
}
</script>
To make the chatbox more realistic view, add these CSS style codes.
<style>
.chat-box {
height: 500px;
width: 100%;
overflow: scroll;
}
.chat-item {
border: none;
}
.chat-status {
min-height: 49px;
}
.chat-status .chat-date {
display: block;
font-size: 10px;
font-style: italic;
color: #999;
height: 15px;
left: 10%;
right:10%;
}
.chat-status .chat-content-center {
padding: 5px 10px;
background-color: #e1e1f7;
border-radius: 6px;
font-size: 12px;
color: #555;
height: 34px;
left: 10%;
right:10%;
}
.chat-message {
width: 80%;
min-height: 40px;
}
.chat-message .right-bubble {
position: relative;
background: #dcf8c6;
border-top-left-radius: .4em;
border-bottom-left-radius: .4em;
border-bottom-right-radius: .4em;
padding: 5px 10px 10px;
left: 15%;
}
.chat-message .right-bubble span.msg-name {
font-size: 12px;
font-weight: bold;
color: green;
display: block;
}
.chat-message .right-bubble span.msg-date {
font-size: 10px;
display: block;
}
.chat-message .right-bubble:after {
content: '';
position: absolute;
right: 0;
top: 0;
width: 0;
height: 0;
border: 27px solid transparent;
border-left-color: #dcf8c6;
border-right: 0;
border-top: 0;
margin-top: -0.5px;
margin-right: -27px;
}
.chat-message .left-bubble {
position: relative;
background: #efefef;
border-top-right-radius: .4em;
border-bottom-left-radius: .4em;
border-bottom-right-radius: .4em;
padding: 5px 10px 10px;
left: 5%;
}
.chat-message .left-bubble span.msg-name {
font-size: 12px;
font-weight: bold;
color: blue;
display: block;
}
.chat-message .left-bubble span.msg-date {
font-size: 10px;
display: block;
}
.chat-message .left-bubble:after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 0;
height: 0;
border: 27px solid transparent;
border-right-color: #efefef;
border-left: 0;
border-top: 0;
margin-top: -0.5px;
margin-left: -27px;
}
footer.sticky-footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 10px;
background-color: #ffffff;
border-top: solid 1px #efefef;
}
</style>
Running the Vue.js and Firebase realtime chat web app is very simple. Just type this command in your terminal.
npm start serve
And here it is, you can test the realtime chat web app in your multiple machine or browser. You can watch this demo to find out how it works with multiple browsers.
That it’s, the Vue.js Firebase Realtime Chat Web App tutorial. You can check the full source code from our GitHub.
Thanks for reading ❤
If you liked this post, share it with all of your programming buddies!
Follow us on Facebook | Twitter
☞ The Complete JavaScript Course 2019: Build Real Projects!
☞ Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)
☞ Nuxt.js - Vue.js on Steroids
☞ Best JavaScript Frameworks, Libraries and Tools to Use in 2019
☞ Build a Progressive Web App In VueJs
☞ Build a CMS with Laravel and Vue
#vue-js #firebase #web-development #javascript