blog

  • Home
  • blog
  • Build a Real-Time Status Update App with AngularJS & Firebase

Build a Real-Time Status Update App with AngularJS & Firebase

If you’ve spent any time with AngularJS then you’ll likely be familiar with Firebase—a realtime data store that makes it very easy to save and sync data across any platform. Firebase provides an AngularJS binding for its platform called AngularFire which makes using the Firebase API even easier.

In this tutorial we will be creating a simple status update app that will let us see how AngularJS and Firebase interact. For the UI, we’ll use Angular Material which is the AngularJS implementation of Google’s Material Design and comes with a large set of great UI components. Angular Material is based on flexbox which might take a bit of getting used to if you haven’t become familiar with it yet. We’re also going to focus a lot on the authentication portion of the app which, as we’ll see, is made simple by Firebase’s built-in authentication system.

Screen shot 1 of real-time status app

This tutorial will assume that you’re familiar with AngularJS and that you have a cursory understanding of what Firebase is and how it works.

As ever, the code for this tutorial can be found on GitHub.

Installing the Dependencies

Let’s start by installing what we’ll need for the app using npm.

From the command line:

mkdir status-app && cd status-app
npm install angular-material angular-ui-router angularfire angular-md5

Installing Angular Material will give us other packages as well, including the most recent version of AngularJS. We’ve included UI Router as we’ll need to handle two different states—one for logging in/registering and another for viewing statuses. Angular MD5 will give us a quick way to hash email addresses which will be needed for getting Gravatar images for our users.

You’ll also need some kind of server to view and interact with the app. For this purpose http-server is ideal.

Setting up the App

We’ll want a folder structure that gives us a clean way of breaking out the different areas of responsibility. For this, let’s use a folder called components. The entire folder structure should look like this:

status-app
|-- components
    |-- auth
    |-- status
    |-- user
|-- node_modules
    * dependencies
-- app.js
-- index.html
-- style.css

Let’s setup our index.html file with references to the dependencies we installed already, as well as the application scripts that we haven’t yet created.

<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <title>Status App</title>
    <link rel="stylesheet" href="node_modules/angular-material/angular-material.css">
    <link rel="stylesheet"
          href="https://fonts.googleapis.com/css?family=RobotoDraft:300,400,500,700,400italic">
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
  <body ng-app="statusApp">
    <div layout="row">
      <div flex="33" offset="33">
        <div ui-view></div>
      </div>
    </div>
  </body>

  <!-- Application Dependencies -->
  <script src="node_modules/angular/angular.js"></script>
  <script src="node_modules/angular-ui-router/build/angular-ui-router.js"></script>
  <script src="node_modules/angular-material/angular-material.js"></script>
  <script src="node_modules/angular-animate/angular-animate.js"></script>
  <script src="node_modules/angular-aria/angular-aria.js"></script>
  <script src="https://cdn.firebase.com/js/client/2.2.6/firebase.js"></script>
  <script src="node_modules/angularfire/dist/angularfire.js"></script>
  <script src="node_modules/angular-md5/angular-md5.js"></script>

  <!-- Application Scripts -->
  <script src="app.js"></script>
  <script src="components/auth/authController.js"></script>
  <script src="components/auth/authService.js"></script>
  <script src="components/status/statusController.js"></script>
  <script src="components/status/statusService.js"></script>
  <script src="components/user/userService.js"></script>
</html>

We’ve bootstrapped the app on the body tag and called it statusApp. We’re also immediately making use of Angular Material in the body by specifying that the opening div tag should have a layout of row. By setting the layout to row, everything inside the container will be placed horizontally. If we were to set the layout to column, everything would be stacked vertically.

In the next div, we’re setting the width to be 33% by putting a value of 33 on the flex attribute. The offset attribute lets us center the element by saying it should be moved over to the right by a third.

The last element is our ui-view tag which is the point at which our (yet to be created) UI Router states will be loaded.

We’ll also need an app.js file to get the application started.

// app.js

(function() {
  'use strict';

  angular
    .module('statusApp', ['firebase', 'ngMaterial', 'angular-md5', 'ui.router'])
    .config(function($stateProvider, $urlRouterProvider) {

    // If a route other than status is requested,
    // go to the auth route
    $urlRouterProvider.otherwise('/auth');

    $stateProvider
      .state('auth', {
        url: '/auth',
        templateUrl: 'components/auth/authView.html',
        controller: 'AuthController as auth'
      })
      .state('status', {
        url: '/status',
        templateUrl: 'components/status/statusView.html',
        controller: 'StatusController as status'
      });
    });
})();

As you’ll see, we’re calling the AngularJS module statusApp which matches up with our ng-app declaration on the body tag. We’ve injected the modules we need by specifying them in the array next to the module name and then setup some configuration for the app. The configuration block is where we’ll setup the rules for UI Router to handle our different states. To make this happen we need to pass the configuration function $stateProvider and $urlRouterProvider.

We’ve yet to setup the actual controllers and templates for these states, but what we’re saying here is that when we are at a URI of /auth, we want to load the auth view and auth controller. This state is responsible for providing a login and registration box for users.

Once logged in, we want to go to the /status state which loads the status controller and view. Finally, we want to negate any other routes so we tell $urlRouterProvider if in doubt, send the user to the /auth state.

A Little CSS

We’ll need a little bit of CSS to style the status listings in our app.

/* style.css */

.face {
  border-radius: 30px;
  border: 1px solid #ddd;
  width: 48px;
  margin: 16px;
}

.remove-status {
  cursor: pointer;
  color: red;
  font-weight: bold;
}

Handling Authentication

Our app is going to need to be able to register and authenticate users and fortunately for us, Firebase provides an easy to use, hosted solution for authentication. While it offers ways to authenticate with Google, Facebook and others, we’re going to keep things simple by relying on their email and password method.

NOTE: The code samples reference my own Firebase app that I’ve created which you are free to use. Alternatively, you may create your own Firebase account and change up the references to in the code to point to it. To do so, see the section Adding Your Own Firebase Account at the end of the article.

First, let’s create an authentication service.

// components/auth/authService.js

(function() {
  'use strict';

  angular
    .module('statusApp')
    .factory('Auth', AuthService);

  function AuthService($firebaseAuth) {
    var ref = new Firebase("https://statusapp.firebaseio.com");
    return $firebaseAuth(ref);
  }

})();

We give this factory a name of Auth and setup a connection to the already-created Firebase app called statusapp. We pass our application reference to $firebaseAuth which is the service responsible for handling the Firebase authentication methods. Returning this from our Auth service will allow us to hook into it from our controller.

Next, let’s setup the authentication controller with some methods that will login and register users.

Continue reading %Build a Real-Time Status Update App with AngularJS & Firebase%

LEAVE A REPLY