Create your account

Already have an account? Login here

Create account

How to Make an Angular Firebase Chat App

By Gary simon - Jan 09, 2017

In this Firebase tutorial, you're going to learn how to make a simple Angular chat app. It can provide you with a great starting point from which to build a more featured chat app for your own projects.

Firebase is a free service that was purchased in 2014 by Google, and it's great for to use as a basis for creating chat systems.

Our firebase chat app will use Facebook to handle logging in, though you can very easily extend this app on your own to include other login systems such as Twitter, Github, Google, Email/Password and Anonymous.

I'm going to assume you know the basics of Angular 2+ (If not, you can read/watch our free angular 2 fundamentals course here). You should obviously know HTML and CSS as well.

Prefer to watch a video instead?

This tutorial has also been recorded as a video tutorial, which you can watch below at the Coursetro youtube channel. Subscribe if you enjoy!

Create your Firebase Account

Before we can begin development, we'll setup the Firebase project as well as ensuring Facebook has the right settings.

Head on over to Firebase and click "Create New Project". Give it a project name such as "mychatapp" and click "Create Project".

Next you will be presented with this screen.

Click on "Add Firebase to your web app" and copy the following information to a text file for later reference. We'll define this information in our app.module.ts shortly.

Close the popup, and on the left menu click "Authentication" and then the "SIGN-IN METHOD" tab at the top.

Click on Facebook and slide the "Enable" toggle to on.

Now, head on over to Facebook Developers in a new browser tab. If you don't already have an app created, create a web app through their system. Once finished, on the Dashboard page, it will provide you with the App ID and the App Secret as requested at Firebase.

Paste in your App ID and App Secret, and then click the copy icon to copy the OAuth redirect URI.

Switching back over to Facebook, click on "Facebook Login" on the left sidebar, and paste in your OAuth redirect URI in the "Valid OAuth Redirect URIs". Then hit "Save Changes".

 

Next, in Firebase, click on the "Database" link on the left sidebar, and then the "Rules" tab on the top.

For development purposes, copy and paste this below to change the our firebase project rules:

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

The result will look like this:

Setting up the Project

Now that we have Firebase all setup and ready to go, as well as Facebook, let's start building the project out with Angular.

First, make sure you have the angular-cli installed by typing ng-v at the command line. If it's unrecognized, head on over to angular-cli for installation instructions (you will also need nodejs with npm).

> ng new mychatapp
> cd mychatapp

Let ng new install the new project, and then cd into the project folder.

Next, we need to use npm to install angularfire2 and firebase with the --save flag.  --save will add it to the package.json as a dependency.

> npm install angularfire2 firebase --save

Adding the Firebase Project Settings

Remember when I told you to save your firebase project settings?  We need them now.

Open up your newly created Angular project in your code editor of choice, and navigate to: /src/app/app.module.ts

First we need to import the AngularFireModule, so add it to the top of app.module.ts:

import { AngularFireModule } from 'angularfire2';

And underneath that, we need to export firebaseConfig, which is where you will define your firebase project settings:

// Must export the config
export const firebaseConfig = {
  apiKey: '',
  authDomain: '',
  databaseURL: '',
  storageBucket: '',
  messagingSenderId: ''
};

And then finally, in @NgModule, we must add AngularFireModule that we imported earlier, inside imports:

imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AngularFireModule.initializeApp(firebaseConfig)
  ],

Great! Now our angular firebase app is ready to rock n' roll.

Necessary Firebase Imports

The rest of our work will take place in /src/app/app.component.ts. This is a fairly simple app, so we only need to work with 1 component here.

 

At the top of app.component.ts, underneath our imported Component, we need to import the following angularfire-specific functions.

import { Component } from '@angular/core';
import { AngularFire, AuthProviders, AuthMethods,FirebaseListObservable } from 'angularfire2';
  • AngularFire is needed as the primary AngularFire member.
  • AuthProviders and AuthMethods are both used for Firebase authentication.
  • And FirebaseListObservable allows us to fetch the chat messages.

Required Properties

We need to declare just 3 properties at the top of export class AppComponent.

export class AppComponent {
  items: FirebaseListObservable<any>;
  name: any;
  msgVal: string = '';
  • The items property is set to the FirebaseListObservable. This helps fetch the messages from Firebase.
  • The name property is something we'll set to check if the auth is successful.
  • msgVal we're using for property binding, which will allow us to clear the text input field after a user hits Enter to submit a new chat message.

Working with the Constructor

We'll use dependency injection in our constructor to work with AngularFire that we imported at the top. Then we'll reference the items property to grab all of the messages from Firebase and use a query property limitToLast to limit the number of messages shown.

Then we use the subscribe method after a user connects their facebook account, and set the name property to the result.

  constructor(public af: AngularFire) {
    this.items = af.database.list('/messages', {
      query: {
        limitToLast: 5
      }
    });

    this.af.auth.subscribe(auth => { 
      if(auth) {
        this.name = auth;
      }
    });

  }

Creating a Login Method

Still working within export class AppComponent { }, let's create a login method that we'll call in our HTML template once a user clicks a button to login with facebook.

 login() {
    this.af.auth.login({
      provider: AuthProviders.Facebook,
      method: AuthMethods.Popup,
    });
  }

.login() is a method provided by the AngularFire function that allows us to define 2 properties:

  • provider: You can set this to AuthProviders.Facebook, or .Anonymous, .Twitter, .Github, or .Password for custom email and password signups.
  • method: This accepts either AuthMethods.Popup or AuthMethods.Redirect. Redirect will take the user away entirely from your app, while .Popup "pops" up a new window.

Creating a ChatSend Method

Once a user hits the enter key, this method will push the new message to AngularFire.

chatSend(theirMessage: string) {
      this.items.push({ message: theirMessage, name: this.name.facebook.displayName});
      this.msgVal = '';
  }

This method takes in theirMessage as an argument, and then we use this.items.push and send their message to a message property, and then we define our own custom property "name", which is tied to this.name.facebook.displayName. This is equivalent to a person's first and last name on Facebook.

Note: You can use console.log(this.name); to see everything that's returned.

And that's it for the component code!  Now the easy stuff is left.

Defining the app.component.html

The HTML is very minimal, as you can see.  However, I still insisted on using the Foundation 6 flex grid, so we'll be importing that CSS in shortly. For now, copy and paste this HTML in your app.component.html.

<div class="row columns">
  <button (click)="login()" *ngIf="!name">Login With Facebook</button>

  <input type="text" id="message" *ngIf="name" placeholder="Chat here..." (keyup.enter)="chatSend($event.target.value)" [(ngModel)]="msgVal" />

    <div class="chat-container" *ngFor="let item of items | async">
      <a href="#">{{item.name}}</a>
      
      <p>{{item.message}}</p>
    </div>
</div>

What's happening here?

  • The button line is using event binding (click) and calling the login() method. We're also using the *ngIf conditional to designate whether or not this button shows if the name property exists. If it exists, we hide it.  
  • Our input textfield also uses *ngIf to show only if the name property eixsts. We also use event binding (keyup.enter) to call our chatSend method, which sends the value entered through $event.target.value.
  • Then we use *ngFor to iterate through the items array with the async pipe.
  • And finally we use simple interpolation to show the name and message property stored at Firebase.

Defining the app.component.css

Not too much CSS happening here!

input#message {
    background:none;
    border:none;
    border-bottom: 1px solid #4C4C4C;
    outline:none;
    box-shadow:none;
    color: white;
    font-size:1.6em;
    font-weight:300;
    margin-bottom: 3em;
    padding:1.2em 0;
}

.chat-container {
    display:block;
    width:100%;
}
.chat-container:nth-child(4) {
    opacity: .8;
}
.chat-container:nth-child(3) {
    opacity: .6;
}
.chat-container:nth-child(2) {
    opacity: .4;
}

.chat-container a {
    text-transform: uppercase;
    font-weight:bold;
    color:#816A98;
    font-size:.8em;
    letter-spacing:2px;
}

.chat-container p {
    background:#323035;
    padding:1.1em;
    color:white;
    margin: 5px 0 10px 0;
}

Defining the /src/styles.css

For global CSS, we only have 3 rulesets:

body {
    background-color:#242226;
    padding-top: 5em;
}
* {
    font-family: 'Raleway';
}
button {
    background:#4267B2;
    color:white;
    padding: 1.2em;
    width:300px;
    text-align:center;
    font-size:1.2em;
    margin-bottom: 30px;
    cursor:pointer;
}

Importing Foundation & a Web Font to /src/index.html

Within the <head> tags we add:

  <link media="all" type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.0/css/foundation-flex.min.css">
  <link href="https://fonts.googleapis.com/css?family=Raleway:300,500" rel="stylesheet">

This will give us the Foundation 6 Flex Grid, as well as a font from Google Fonts called Raleway.

Run the Angular Firebase Chat App!

Now in the console, we get to the project and view it in all it's glory!

> ng serve

If everything goes to plan, head on over to http://locahost:4200 in your browser.

It should show you the Facebook login button initially. Click it, and then connect your facebook, and start typing messages to yourself like a mad man.  Get up a couple chat windows and watch that beautiful live async chat action occur.

Going Further

Now, of course this is a very simple, rather unusable example. But you can very quickly use this to create something much more robust. Your most immediate concern would be handling logouts for instance!

That's easy. Just create a logout button in the HTML, use event binding to call a logout() method, and then define that method in your app.component.ts.

Something like:

logout() {
     this.af.auth.logout();
  }

..should work just fine!


Share this post




Say something about this awesome post!