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.
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.
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.
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-projectnpm installnpm 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
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.
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.
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.
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.
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.
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:
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.
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.
Next, we need to render the data in HTML level when the message variable change. Add the code below to inside the template tag.
<div v-for="msg in messages">{{msg.message}}</div>
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.
Finally, there are some important points in this tutorial:
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.