Build a Location-based Chatroom with Firebase and Vue.js

Build a Location-based Chatroom with Firebase and Vue.js

Build a Location-based Chatroom with Firebase and Vue.js

Introduction

Recently, me and my friend built a location-based chatroom called — Near (https://near.idgo.me). People can talk with each other nearby in a web app. We would like to share what we did and how to make it. Please feel free to give us feedback by replying this article.

Prerequisites

  1. Basic Knowledge of Geohash
  2. Basic knowledge of Firebase
  3. Basic knowledge of Vue.js component

What We Want to Achieve?

In this tutorial, we would try to make it as simple as possible so that you can see the effect quickly. So, the following steps we will be covered today.

  1. Get the user’s position via Geolocation API and convert the latitude and longitude into geohash
  2. Send a message to a room
  3. Display messages

What is Geohash?

Before talking about how to do it, we would like to briefly introduce what the geohash is. Geohash is a geocoding system which will be used to define a chatroom in this tutorial.

For example, wecnvgm2re3u represents Tsim Sha Tsui in Hong Kong (Latitude and Longitude = 22.29818732, 114.16646970). Each geohash character represents an area of the world and more character means more specific to a place. You can use this tool to know how it works.

In this application, geohash is an ideal mechanism to define a room ID based on user’s location and use the geohash precision (the length of geohash) to define the area coverage.

Create a Vue Project

In this article, we use vue-cli to generate a Vue seed project.

Install vue-cli

Root permission may be needed

npm install -g vue-cli

Initialize a vue project via vue-cli

vue init webpack-simple my-project

In this tutorial, we use webpack-simple template as a demo. For more detail about vue-cli, please see here.

Install dependencies and run the project by the following commands

cd my-project
npm install
npm run dev

Now, you can access your project on localhost:8080

After we created a Vue project and installed the dependencies, we can start to work on the Vue component (my-project/src/App.vue). If you are not familiar with Vue single file component, you can see the official website.

Next, try to modify your script to become the following structure. Inside the component, add some data variables to store the chatroom information.

room — A Firebase reference object which represents the room

precision — A precision of the geohash (default is 6 in this tutorial)

**db **— A Firebase SDK to communicate with Firebase

export default {
  name: 'chat',
  data() {
    return {
      room: null,
      precision: 6, // default precision
      db: null // assign Firebase SDK later
    }
  },
  mounted() {

  },
  methods: {
  }
}

chatroom-vue-component.md

Install Firebase and Geohash Encoder

Apart from Vue.js, we need Firebase SDK to communicate with Firebase and use geohash converter package to encode the latitude and longitude to geohash (room ID). You can install the these two packages by the following command.

npm install --save firebase latlon-geohash

After installing these two packages, you can import them inside the script tag in App.vue. For the Geohash package, we will explain it later.

import * as Firebase from 'firebase'
import Geohash from 'latlon-geohash'
export default{
// ....
}

Initialize Firebase When the Component Is Ready

When Vue component is ready, the mounted hook will be called. So, we can initialize a Firebase client object and assign it into a variable called — db. Remember to put your Firebase credential e.g. apiKey, authDomain, databaseURL and projectId as parameters. We assume that you know how to set up a Firebase project and obtain the credential. If you have no idea how to set it up, go to Firebase Get Started Guide.

import * as Firebase from 'firebase'
import Geohash from 'latlon-geohash'
    
export default {
  // ....
  mounted () {
    // init the database client by given Firebase's API key
    this.db = Firebase.initializeApp({
        apiKey: '',
        authDomain: '',
        databaseURL: ''
    })
  }
}

mounted.md

Dependencies are Ready. It is time to Build.

1. Get the user’s position and convert the latitude and longitude into geohash

In this step, we will create a method called — init() to access user’s location via Geolocation API and convert it into geohash so that we can define which room should they go.

When the geolocation is obtained, we use the Geohash encoder imported before to convert the location into geohash.

For example:

Location: 22.29818732, 114.16646970 => wecnvg (geohash)

Since we set the default precision is 6, encoder only returns 6 characters. When we get the geohash, we initialize a Firebase reference with the room ID (geohash) and assign the reference to the room variable which can be reused later.

import Firebase from 'firebase'
import Geohash from 'latlon-geohash'
    
export default {
  // ....
  methods:{
    init() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition((position) => {
          var geohash = Geohash.encode(position.coords.latitude, position.coords.longitude, this.precision);

          // initilize the room based on geohash
          this.room = this.db.database().ref().child('rooms/' + geohash)
        }, (err) => {
          // error handling here
        })
      } else {
        console.error('Cannot access geolocation')
      }
    }
  }
}
          

chatroom-init.md

OK. The init method is completed, but we still need to call it when the component is ready. So, call init method inside the mounted hook. Like the code below. Then, the component will try to access user’s location when the component is ready.

import * as Firebase from 'firebase'
import Geohash from 'latlon-geohash'

export default {
    name: 'chat',
    data() {
        return {
            room: null,
            precision: 6,
            db: null
        }
    },
    mounted() {
        this.db = Firebase.initializeApp({
            apiKey: '',
            authDomain: '',
            databaseURL: '',
            storageBucket: '',
            messagingSenderId: ''
        })

        // access the location and initilize a Firebase reference
        this.init()
    },
    methods: {
        init() {
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition((position) => {
                    var geohash = Geohash.encode(position.coords.latitude, position.coords.longitude, this.precision);

                    // initilize the room based on geohash
                    this.room = this.db.database().ref().child('rooms/' + geohash)
                }, (err) => {
                    // error handling here
                })
            } else {
                console.error('Cannot access geolocation')
            }
        }
    }
}   

complete-js-1.md

2. Create an input element to send a message

Create an input element inside template tag in the component (App.vue). We use v-model messageInput to store the message and use trim to remove the leading space of the input. When user presses the enter in the input element. The method send(messageInput) will be called. Remember to create a messageInput key inside the data part.


    
        
    

send message.md

Now, we are going to implement the send(messageInput) method to handle the event from the input element. Inside this method, we simply create an temporary object with a key called — message to store the message body. After that, call the push() to obtain a key and set the value on that key afterwards.

Remember to clean the messageInput value when the message is sent. Otherwise, your input always be there.

export default {
  // ..
  data () {
    return {
      // ..
      messageInput:'' // this is for v-model
    }
  },
  methods : {
    send(messageInput) {
      // A data entry.
      let data = {
        message: messageInput
      };

      // Get a key for a new message.
      let key = this.room.push().key;
      this.room.child('messages/' + key).set(data)
      
      // clean the message
      this.messageInput = ''
    }
  }
}

sendMessage.md

When you press the enter, probably get an error in your browser console. The image below is from Chrome console.

Don’t worry. Since Firebase only allows authorized user to access by default, so you need to enable a permission for that.

Follow the steps below to enable the permission:

  1. Go to Firebase console
  2. Select your project
  3. Select Database section

You can see the JSON in Rules section and see the default setting.

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

We want to see the effect quickly. We enable anyone can access Firebase by the following setting. (This approach is for demo only. Don’t do it in production).

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

After published the rules, you can try to send a message again. There is no error anymore. If you can access Firebase console, you can see the data from your input (Like the image below).

Notes: Since geolocation is an async process (in step 1), the geolocation cannot be obtain immediately. So, it is good to add a flag to indicate the geolocation is ready. Otherwise, an error will be thrown when you send a message because the room ID (Geohash) is not ready.

3. Display messages

We have already known how to send a message to Firebase. Now, we are going to create a listener to listen to an event from Firebase and display the messages when they comes.

The code below shows how to create an event listener and activate the event listener after the room is selected. When a new message added into Firebase, an event child_added will be triggered and run the callback method with a snapshot data. If you don’t know how Firebase works, good to read the tutorial here. Inside the callback method, the snapshot of the data will be pushed into the messages variable.

export default {
  // ...
  data () {
    return {
      // ...
      messages: []
    }
  },
  methods : {
    init() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition((position) => {
          var geohash = Geohash.encode(position.coords.latitude, position.coords.longitude, this.precision);

          // initilize the room based on geohash
          this.room = this.db.database().ref().child('rooms/' + geohash)
          
          // must call messageListener() to listen to the new message event
          this.messageListener()
        }, (err) => {
          // error handling here
        })
      } else {
        console.error('Cannot access geolocation')
      }
    },
    messageListener () {
      this.room.child('messages').on('child_added', (snapshot) => {
        // push the snapshot value into a data attribute
        this.messages.push(snapshot.val())
      })
    }
  }
}

messageListener.md

Next, we need to render the data in HTML level when the message variable change. Add the code below to inside the template tag.

{{msg.message}}

Since the basic data structure of a message in Firebase in Step 2 is the following:

{
  "message":"my message"
}

So, in the HTML level, we can access msg.message to display the data. When you send a message, a new message will show.

Combine Together


    
        
        {{msg.message}}

    



complete-1.md

Final View

Conclusion

Finally, there are some important points in this tutorial:

  1. Make sure you have permission to access Firebase
  2. Since getting the geolocation is an async process, make sure you have obtained the geolocation before sending a message to Firebase.
  3. Create appropriate variable(s) in each section
  4. Activate the event listener to listen to new messages

There is a completed application — https://near.idgo.me

Feel free to give us feedback. No matter it is good or bad. In addition, we will prepare part 2 to make the chatroom more fun.

30s ad

VueJS V1 Introduction to VueJS JavaScript Framework

Getting started with Vuejs for development

Vuejs 2 + Vuex + Firebase + Cloud Firestore

Building Applications with VueJs, Vuex, VueRouter, and Nuxt

Ethereum and Solidity: Build Dapp with VueJS

What are the differences between the various JavaScript frameworks? E.g. Vue.js, Angular.js, React.js

What are the differences? Do they each have specific use contexts?

What are the differences? Do they each have specific use contexts?

Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

In this article we will discuss full details and comparison of both Ember.js and Vue.js

JavaScript was initially created to work for web applications. But today they have become the favorite of mobile app developers. Most of the developers prefer to work with frameworks based on JavaScript. It simplifies coding. You can use JavaScript with almost any framework.

The use of a particular framework will decide how easy and fast it is to create the app. So, you must choose the best one suited for the app that you are planning to build. You must make a wise choice so that you benefit in the end. Among the crowded market, two of the frameworks stand out. We will make a comparison between Ember.js and Vue.js.

Why Do You Select A Particular Framework?

Before we start comparing the two frameworks, we should understand the factors that lead to the choice of a framework. Each developer chooses a framework before he or she goes to work on an app. Let us see the reasons for the selection.

● The codes must be easy to understand and transparent.

● The framework should give the maximum power with the least amount of coding.

● The framework should provide a well laid out structure to work on.

● Does the framework support an in-built router or an external plug-in router?

● The framework should be able to transfer more data on a full page-load so that it becomes a single-page app. A single-page app is more beneficial for the application.

● In single page architectures if there is a need for users to share links to sub-screens within the interface, then the framework should have the capacity to route based on the URL.

● A tighter template option can help in enabling two-way binding.

● The framework should not conflict any third-party library.

● Testing the codes inside the framework should be easy.

● The framework should provide the HTTP client service for AJAX calls

● The documentation is essential. It should be complete and up-to-date.

● The framework should be compatible with the latest version of the browser.

● The framework has to fulfill the above conditions for easy construction of the app. You must ensure that the framework you choose meets the conditions.

Vue.js Explained

Developers are always looking at new frameworks to build their apps. The main requirements are speed and low cost. The framework should be easy to use by even new developers. You should be able to use it at low cost. Other considerations are about simple coding, proper documentation, etc.

Vue.js combines a lot of good when it comes to software language for web app development. The architecture of Vue.js is easy to put in use. The apps developed using Vue.js are easy to integrate with new apps.

Vue.js is a very lightweight framework. It makes it fast to download. It is also much faster than other frameworks. The single-file component nature of the framework is also beneficial. The size has made it very popular.

You can further decrease weight. With Vue.js you can separate the template-to-virtual DOM and compiler. You can only deploy the minified and zipped interpreter which is only 12 KB. You can compile the templates in your machine.

Another significant advantage of Vue.js is that it can integrate easily with existing applications created with JavaScript. It will make it easy for using this framework to make changes to applications already present.

Vue.js also integrates easily with other front-end libraries. You can plug in another library and make up for any deficiency in this framework. This feature makes this tool a versatile one.

Vue.js uses the method of rendering on the streaming-side server. You can render your component and get a readable stream. You can then send this to the HTTP server. It makes the server highly responsive. Your users will get the rendered content very quickly.

Vue.js is very SEO friendly. As the framework supports server-side rendering, the views are rendered directly on the server. The search engines list these.

But the most important thing for you is the ease with which you can learn Vue.js. The structure is elementary. Even new developers will find it easy to use it to build their apps. This framework helps in developing both small and large templates. It helps to save a lot of time.

You can go back and check your errors very easily. You can travel back and inspect all the states apart from testing your components. It is another important feature as far as any developer is concerned.

Vue.js also has very detailed documentation. It helps in writing your applications very quickly. You can build a web page or app with the basic knowledge of HTML or JavaScript.

● Vue.js has pure architecture. It helps in integration with other apps

● Vue.js is lightweight and fast. It can be made lighter by deploying only the interpreter

● You can separate the compiler and the template-to-virtual DOM.

● Due to smooth integration, you can use this to make changes to existing apps

● To make up for any shortfall, you can plug-in any library and makeup.

● As Vue.js uses streaming-side server rendering, your users can get quick responses.

● The server-side rendering also helps in being ranked higher by search engines.

● It has a simple structure. Easy to use for any new developer

● You can go back and check and correct your errors.

● You can check all the existing states.

● Detail documentation also helps build the web page or application very quickly.

Ember.js Decoded

Ember.js is an MVVM model framework. It is open-source software. This platform is mostly used for creating complex multi-page applications. It maintains up-to-date features without discarding any of the old features.

With this framework, you have to follow the architecture of the framework strictly. The JS framework is very tightly organized. It reduces the flexibility that other frameworks might offer.

There is a very refined and developed control system for its platforms and tools. You can integrate it with the new version with the tools provided. There is strict guidance about avoiding outdated APIs.

You can understand Ember’s APIs easily. They are also easy to work. You can make use of highly complex functionalities simply and straightforwardly.

The performance is better as similar jobs are processed together. It creates batches of similar bindings and DOM updates to improve the performance. It means that the browser needs to process them in one go. It will avoid recomputing for each task, wasting a lot of time.

You can write the codes in a simple manner and modules. You can use any of Ember’s APIs. It is possible due to the presence of Promises everywhere.

Ember comes with a well-written guide. The API is recorded in a useful manner. It is a front-end framework that is loaded. Ember has a router, pipeline, services, etc. of its own.

The basis for views, controllers, models, and framework is the Ember Object Model. All components come from the same objects. The framework is firm and steady. The reason is that all elements have similar jobs and characteristics.

Ember has made the general application, organization, and structure clear so that you don’t make any mistakes. You will have no chance to complicate the application unnecessarily. If you have to go out of the defined limits, you will have to force your way out.

The language used for templating in Embers is Handlebars. This language helps Embers to keep its logic out of view. The clean syntax of Handlebars makes it easy for you to read and understand the templates. Handlebar templates are faster to load.

Another advantage you gain from Handlebar is that you don’t have to update your template every time you add or remove data from the page. It will be done automatically by the language itself.

A community that is continually improving the framework supports Ember. They are updating the framework with the latest technology. They also make sure that backward compatibility is possible.

● Ember.js is an open-source MVVM model framework suitable for complex multiple-page applications.

● It offers both the latest and old features.

● It has a very tightly structured framework which doesn’t offer much flexibility

● A very refined control system helps you to integrate with new versions without any problem.

● There is strict guidance about avoiding outdated API versions.

● Ember’s APIs help you to use complex functionalities in a simple manner

● There is no recomputing for each task as the framework allows the browser to do similar functions together.

● Promises allow you to write modular and straightforward code using any API of Ember.js.

● Ember.js is a fully loaded, front-end framework.

● The framework is stable because all components have the same functionalities and properties.

● It has well-defined limitations which will prevent your complicating your application

● Handlebars, the language used by Ember.js allows you to read and understand templates easily. It also helps to load the templates faster.

● Handlebars will ensure to update the template every time you add or remove data.

● Ember.js has an active community that updates the framework regularly and facilitates backward compatibility.

A Comparison Between Ember.js And Vue.js

This article intends to compare the features of both frameworks. Let us see how the characteristics of these frameworks compare. It will help you to make use of the right framework for your web application.

When you need a modern engine for an old application, it is Vue.js which will help you. It combines the best properties of other frameworks. Vue.js is a developing framework. A ready-to-use library of interface elements does not exist. However, many third-party libraries can help you.

Ember.js offers you a well-organized and trustworthy framework. When the development team is big, this is the framework that suits best. It allows everyone to understand the written code and contribute to a common project. The technology will be up-to-date, and the platform will be stable.

Vue.js can help you use the syntax of different kinds. It helps in writing the codes with ease. It is also an SEO friendly framework. Ember is a fully loaded front-end framework and can help you develop the applications very fast. But it is not suitable for developing small projects.

It is not easy to say this is better than that. It will depend on what kind of project you have undertaken. Both have their pluses and minuses. The below table will help in a better comparison.

Final Thoughts

It is not easy to conclude as to which is better. It all depends on the application that you want to develop. Both frameworks are developing. Both are getting updates. Both the communities are working on the frameworks.

While Vue.js is more comfortable for writing codes, Ember is a full-stack framework allowing the development of apps very fast. It is suitable for big projects. It is too complicated to be used for smaller projects.

We hope you had a great time reading this article. If you’ve any questions or suggestions related to this blog, then feel free to ask them in the comment section. Thank You.!