Saturday 26 April 2014

Implementing a login with Firebase and Angularjs

The topic of this article is to present to you how to use Firebase and Angularjs in an application. The aim is to get a quick look on how to implement a login with Firebase and Angularjs in a simple application. In order to get the display more user-friendly, Bootstrap CSS and JQuery will be used.
Explanations will be completed with code snippets and a link to a Github repository will be provided for testing a real example.

Here is the plan of this article:
  • PART 1: A presentation of Firebase
  • PART 2: A presentation of Angularfire
  • PART 3: Creating and setting an application in Firebase
  • PART 4: Overview of the application with login
  • PART 5: Defining the service for connecting to Firebase
  • PART 6: Defining the login controller
  • PART 7: Make it work all together
  • PART 8: Getting a working example


PART 1: A presentation of Firebase

Firebase is a backend in the cloud that provides an API for storing and synchronizing data. Developers can focus on implementing the client-side of their application and all the server-side part is handled by Firebase. The developers only need to include a Firebase library in their application; there are libraries for the following support : Web, Nodejs, Objective-C and Java.
If the synchronization of data gives Firebase the advantage of building real-time application easily, you can use Firebase as soon as you do not want to write any single line of code on server side. However Firebase has also some limitations: it is not possible to perform some actions specific to servers such as sending emails. Heavy data processing is not recommended either.
Another key feature of Firebase is security. A large bunch of authentication is provided for securing your applications. The access to an application can be configured through a set of rules that can be defined in the Firebase online interface.
In the application described in PART 4, I will use the web library (javascript) provided by Firebase. I will implement a login form for accessing the application in order to introduce the security mechanism put in place in Firebase.


PART 2: A presentation of Angularfire

As I will develop my application using Angularjs, I will use an Angularjs binding for Firebase which is called AngularFire. This binding is a javascript library that helps you synchronizing and fetching Firebase data by linking Firebase URLs with Angularjs models. AngularFire just exposes the same API as Firebase with an Angularjs function name style.


PART 3: Creating and setting an application in Firebase

The first step for getting a Firebase application (after signing up Firebase) is to create a Firebase application. In order to create an application when you are logged in Firebase, you just need to type the name of your application in the top-left corner of your dashboard and click on the "CREATE NEW APP" button.


When the application has been created, you can select it from your dashboard. As soon as you have selected the application, you are redirected to the "Data" tab of the application.


The "Data" tab is where you can view the data that are currently stored in your application. As you can see on the screenshot, you are able to export or import the application data as Json format.
Then you need to go to the "Security Rules" tab in order to secure you application and define who have access to the application data and to which data they have access to. The rules are defined as Json format. For more information about the security rules, you can have a look to the security rules section. In the application example, the access to the data in write and read mode are only restricted to authenticated users.


Then you need to define the authentication providers when the users want to log in. In the application example, the "Email & Password" provider has been enabled. You are also able to specify for which domain you want to allow the simple login service (localhost and 127.0.0.1 in the example).


If you have selected the "Email & Password" authentication provider, you can add some users by entering their email and password.


When your application has been created and the settings are correctly set for the simple login service, it is time to code... But first, let's have a look to the application we would like to implement as an example.


PART 4: Overview of the application with login

The application will only implement a login form, and then (when the user is logged in) a single page with a toolbar and a welcome message to the user (with its email displayed).


When the user is logged in and he is on the dashboard, he is able to log out when clicking the icon displayed in the left part of the toolbar.


The index.html page of the application should at least include the angular, the firebase, the firebasesimplelogin and the angularfire javascript files. These files can be dowloaded from the official webdite of angularjs and firebase or included from an online repository (like cdnjs for instance).


PART 5: Defining the service for connecting to Firebase

The connection to Firebase services will be defined in an angular service defined in a specific module to keep all the logic in one place. The service will provide 3 functions: one for getting a reference to firebase data, one for login and one for logout. As login and logout functions are asynchronous functions, they will raise an event when user has been logged in (loginsuccessed or loginfailed) and when the user has logged out (logoutsucceded).
The login and logout functions will rely on the FirebaseSimpleLogin API provided by Firebase.

var base = new Firebase(FIREBASE_URL);
var auth = new FirebaseSimpleLogin(base, function(error, user) {
  if (error) {
    // an error occurred while attempting login
    // Perform logic when login failed
  } else if (user) {
    // user authenticated with Firebase
    // Fire event when logged in
  } else {
    // user is logged out
    // Fire event when logged out
  }
});

var service = {};
service.login = function(email, password) {
  auth.login('password', {
    email : email,
    password : password
  });
};
service.logout = function() {
  auth.logout();
};
service.getBase = function() {
  return base;
};

All this logic will be implemented in an angular service returned by an angular 'factory'. The constant 'FIREBASE_URL' is the URL of your firebase application. Firing event is performed by '$rootScope.$broadcast' function.


PART 6: Defining the login controller

The login firebase service implemented above will be used in an angular controller dedicated for managing the login and the switching between the login form and the application home page.

You first need to specify the dependency on the angular module of the firebase service when declaring the application module:

var firebaseangularapp = angular.module('firebaseangularapp', ['ngRoute', 'firebase', 'firebasemodule']);

Then you can declare your login controller in the application module as follow:

firebaseangularapp.controller('LoginCtrl', ['$scope', '$firebase', 'firebaseservice', function LoginCtrl($scope, $firebase, firebaseservice) {
  // TODO
}]);

In the login controller, let's declare the user email and the user password data in order to use them in the login form page. Let's also declare the login and logout function. All these data and functions should be declared in the '$scope' variable in order to be accessible from the html. The logged boolean will be useful for switching from the login form to the home page.

firebaseangularapp.controller('LoginCtrl', ['$scope', '$firebase', 'firebaseservice', function LoginCtrl($scope, $firebase, firebaseservice) {
  $scope.logged = false;
  $scope.useremail = "";
  $scope.userpassword = "";
  $scope.login = function() {
    if ((this.useremail !== "") && (this.userpassword !== "")) {
      firebaseservice.login(this.useremail, this.userpassword);
    }
  };
  $scope.logout = function() {
    firebaseservice.logout();
  };
}]);

When the user will click on the Login button of the login form, the login function of the login controller will be called. This function will call the login function of the firebase service. When the user will be logged in in Firebase and when the service will fire the loginsucceded event through the '$rootScope', this event needs to be intercepted in the login controller to know if the user is logged in or if the login failed. This is done by listening to the event with the '$on' function of the '$scope' object.

$scope.$on('loginsucceeded', function(e, args) {
  $scope.logged = true;
  $scope.apply();
};

The '$scope.apply()' instruction forces the refresh of the scope to keep it up to date with the latest changes.


PART 7: Make it work all together

Now let's have a look at the html. The index.html page will link the logic described above to the displayed page.

<html ng-app="firebaseangularapp">
  <head>
    <!-- Include all the js and css files -->
  </head>
  <body ng-controller="LoginCtrl">
    <div ng-if="!logged">
      <!-- the html for the login form -->
    </div>
    <div id="output" ng-if="logged">
      <header>
        <!-- the html for the navbar -->
      </header>
      <div ng-controller="MainCtrl">
        <!-- the html for the home page main content -->
      </div>
    </div>
  </body>
</html>

The 'MainCtrl' is the controller for the home page main content that will be displayed under the navigation bar after the user logs in.


PART 8: Getting a working example

You can find a working example in my github repository (the firebaseangularapp folder). Please do not forget to declare your own firebase application URL in the firebasemodule.js file in constant 'FIREBASE_URL'.