Gustav Ehrenborg fullstack developer

Email symbol LinkedIn logo GitHub logo Instagram logo

Firebase basics Building a chat using a realtime database

Wednesday, March 15, 2017
The chat is working

Firebase is a platform as a service (PaaS) that provides storage, hosting, serverless functions, authentication, etc... I held a talk on the basics and I showed how to build a chat, here is the chat part in text.

Let's build a chat!

Setup

Run the following commands. Readline is used to read input in the terminal and firebase-admin is the admin package of Firebase. We use the admin package since we don't want to care about admin access.

$ mkdir chatten
$ cd chatten
$ npm init
$ npm i readline firebase --save
$ touch index.js

We also need to setup a Firebase project, and we just need the realtime database.

$ npm i firebase-cli -g
$ firebase init

When creating the Firebase project, select only database, create a new Firebase project and call it whatever you want. You'll be given a database.rules.json file and a project name. Change the database rule file to look like this:

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

The last setup step is to do a `firebase deploy`. The command will initialize the actual database and set the database rules according to the rules file we just changed.

Coding

Import the packages that you just installed and initialize the Firebase app.

const firebase = require('firebase');
const readline = require('readline');
firebase.initializeApp({
  databaseURL: 'https://<your-Firebase-project-name>.firebaseio.com'
});

Create an interface instance for the readline, configuring the standard input and standard output as the input and output streams.

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

Create a reference to the realtime database on Firebase, the 'chat' is the place in the JSON data where the chat messages will be stored.

const chatRef = firebase.database().ref('chat');

Now for the fun part. We want to receive lines from the readline, and the readline has an event called line which contains the entered text. This is perfect. The following code listens to the line event and pushes the data onto the realtime database:

rl.on('line', function(line) {
  chatRef.push({
    text: line
  })
});

When new chat messages are added to the database, we want to show them to the current user. The following code listens for the event 'child_added', which is the event fired when new items are added. The data from the event is then outputted with a simple console log:

chatRef.on('child_added', function(childSnapshot, _) {
  console.log(childSnapshot.val().text);
});

This is out first chat application let try it out. Run `node index.js` in two different terminals and then write some input.

$ node index.js
hello you!
hello you!
How are you?
How are you?
Hello from the second window

That did not quite work as expected. Let's fix this.

Coding continued

The problem is that the code receives the 'child_added' event no matter who wrote it. And we then display the message, resulting in double messages at the sending party. The fix this, we need to give the chat clients an id, that is also saved in the database and when a message is received, we check who wrote it and show it only if it was not the current client.

Add a second attribute to the message we push onto thee database, using this line:

name: process.argv[2]

and change the function that listens to and displays messages to look like this:

chatRef.on('child_added', function(childSnapshot, _) {
  const message = childSnapshot.val();
  if (message.name !== process.argv[2]) {
    console.log(message.name + ': ' + message.text);
  }
});

Now start two clients, and make sure to give them names as a second argument: `node index.js NAME` and select different names. Now enter some text. It will show up at the other client and not be posted twice. The other client can also answer. See the image above. It works! Realtime chat done.

$ node index.js Gustav
Hello there
How are you?
Eric: I'm fine, thank you
$ node index.js Eric
Gustav: Hello there
Gustav: How are you?
I'm fine, thank you

Finally

Have a look at the full code here.