You're viewing the legacy docs. They are deprecated as of May 18, 2016.
These docs are for version 2.4.2 and below of the Javascript SDK. Go to our current docs, or see our Web migration guide.

AngularFire Guide

User Authentication

Overview

Firebase provides a hosted authentication service which provides a completely client-side solution to account management and authentication. It supports anonymous authentication, email / password login, and login via several OAuth providers, including Facebook, GitHub, Google, and Twitter.

Each provider has to be configured individually and also enabled from the Login & Auth tab of your App Dashboard. Select a provider from the table below to learn more.

Platform Description
Custom Generate your own login tokens. Use this to integrate with existing authentication systems. You can also use this to authenticate server-side workers.
Email & Password Let Firebase manage passwords for you. Register and authenticate users by email & password.
Anonymous Build user-centric functionality without requiring users to share their personal information. Anonymous authentication generates a unique identifier for each user that lasts as long as their session.
Facebook Authenticate users with Facebook by writing only client-side code.
Twitter Authenticate users with Twitter by writing only client-side code.
GitHub Authenticate users with GitHub by writing only client-side code.
Google Authenticate users with Google by writing only client-side code.

AngularFire provides a service named $firebaseAuth which wraps the authentication methods provided by the Firebase client library. It can be injected into any controller, service, or factory.

// define our app and dependencies (remember to include firebase!)
var app = angular.module("sampleApp", ["firebase"]);

// inject $firebaseAuth into our controller
app.controller("SampleCtrl", ["$scope", "$firebaseAuth",
  function($scope, $firebaseAuth) {
    var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
    var auth = $firebaseAuth(ref);
  }
]);

Logging Users In

The $firebaseAuth service has methods for each authentication type. For example, to authenticate an anonymous user, you can use $authAnonymously():

Logged in user: {{ authData.uid }}

Error: {{ error }}

var app = angular.module("sampleApp", ["firebase"]); app.controller("SampleCtrl", ["$scope", "$firebaseAuth", function($scope, $firebaseAuth) { var ref = new Firebase("https://docs-sandbox.firebaseio.com"); auth = $firebaseAuth(ref); $scope.login = function() { $scope.authData = null; $scope.error = null; auth.$authAnonymously().then(function(authData) { $scope.authData = authData; }).catch(function(error) { $scope.error = error; }); }; } ]);

Managing Users

The $firebaseAuth service also provides a full suite of methods for managing email / password accounts. This includes methods for creating and removing accounts, changing an account's email or password, and sending password reset emails. The following example gives you a taste of just how easy this is:

Email: Password:



Message: {{ message }}

Error: {{ error }}

var app = angular.module("sampleApp", ["firebase"]); // let's create a re-usable factory that generates the $firebaseAuth instance app.factory("Auth", ["$firebaseAuth", function($firebaseAuth) { var ref = new Firebase("https://docs-sandbox.firebaseio.com"); return $firebaseAuth(ref); } ]); // and use it in our controller app.controller("SampleCtrl", ["$scope", "Auth", function($scope, Auth) { $scope.createUser = function() { $scope.message = null; $scope.error = null; Auth.$createUser({ email: $scope.email, password: $scope.password }).then(function(userData) { $scope.message = "User created with uid: " + userData.uid; }).catch(function(error) { $scope.error = error; }); }; $scope.removeUser = function() { $scope.message = null; $scope.error = null; Auth.$removeUser({ email: $scope.email, password: $scope.password }).then(function() { $scope.message = "User removed"; }).catch(function(error) { $scope.error = error; }); }; } ]);

Retrieving Authentication State

Whenever a user is authenticated, you can use the synchronous $getAuth() method to retrieve the client's current authentication state. This includes the authenticated user's uid (a user identifier which is unique across all providers) and the provider used to authenticate. Additional variables are included for each specific provider and are covered in the provider-specific links in the table above.

In addition to the synchronous $getAuth() method, there is also an asynchronous $onAuth() method which fires a user-provided callback every time authentication state changes. This is often more convenient than using $getAuth() since it gives you a single, consistent place to handle updates to authentication state, including users logging in or out and sessions expiring.

Pulling some of these concepts together, we can create a login form with dynamic content based on the user's current authentication state:

Hello, {{ authData.facebook.displayName }}

Welcome, please log in.

var app = angular.module("sampleApp", ["firebase"]); app.factory("Auth", ["$firebaseAuth", function($firebaseAuth) { var ref = new Firebase("https://docs-sandbox.firebaseio.com", "example3"); return $firebaseAuth(ref); } ]); app.controller("SampleCtrl", ["$scope", "Auth", function($scope, Auth) { $scope.auth = Auth; // any time auth status updates, add the user data to scope $scope.auth.$onAuth(function(authData) { $scope.authData = authData; }); } ]);

The ng-show and ng-hide directives dynamically change out the content based on the authentication state, by checking to see if authData is not null. The login and logout methods were bound directly from the view using ng-click.

User-Based Security

Authenticating users is only one piece of making an application secure. It is critical to configure Security and Firebase Rules before going into production. These declarative rules dictate when and how data may be read or written.

Within our Firebase and Security Rules, the predefined auth variable is null before authentication takes place. Once a user is authenticated, it will contain the following attributes:

provider The authentication method used (e.g. "anonymous" or "google").
uid A user ID, guaranteed to be unique across all providers.

We can then use the auth variable within our rules. For example, we can grant everyone read access to all data, but only write access to their own data, our rules would look like this:

{
  "rules": {
    // public read access
    ".read": true,

    "users": {
      "$uid": {
        // write access only to your own data
        ".write": "$uid === auth.uid",
      }
    }
  }
}

For a more in-depth explanation of this important feature, check out the web guide on user-based security.

Authenticating With Routers

Checking to make sure the client has authenticated can be cumbersome and lead to a lot of if / else logic in our controllers. In addition, apps which use authentication often have issues upon initial page load with the logged out state flickering into view temporarily before the authentication check completes. We can abstract away these complexities by taking advantage of the resolve() method of Angular routers.

AngularFire provides two helper methods to use with Angular routers. The first is $waitForAuth() which returns a promise fulfilled with the current authentication state. This is useful when you want to grab the authentication state before the route is rendered. The second helper method is $requireAuth() which resolves the promise successfully if a user is authenticated and rejects otherwise. This is useful in cases where you want to require a route to have an authenticated user. You can catch the rejected promise and redirect the unauthenticated user to a different page, such as the login page. Both of these methods work well with the resolve() methods of ngRoute and ui-router.

app.run(["$rootScope", "$location", function($rootScope, $location) {
$rootScope.$on("$routeChangeError", function(event, next, previous, error) {
  // We can catch the error thrown when the $requireAuth promise is rejected
  // and redirect the user back to the home page
  if (error === "AUTH_REQUIRED") {
    $location.path("/home");
  }
});
}]);

app.config(["$routeProvider", function($routeProvider) {
$routeProvider.when("/home", {
  // the rest is the same for ui-router and ngRoute...
  controller: "HomeCtrl",
  templateUrl: "views/home.html",
  resolve: {
    // controller will not be loaded until $waitForAuth resolves
    // Auth refers to our $firebaseAuth wrapper in the example above
    "currentAuth": ["Auth", function(Auth) {
      // $waitForAuth returns a promise so the resolve waits for it to complete
      return Auth.$waitForAuth();
    }]
  }
}).when("/account", {
  // the rest is the same for ui-router and ngRoute...
  controller: "AccountCtrl",
  templateUrl: "views/account.html",
  resolve: {
    // controller will not be loaded until $requireAuth resolves
    // Auth refers to our $firebaseAuth wrapper in the example above
    "currentAuth": ["Auth", function(Auth) {
      // $requireAuth returns a promise so the resolve waits for it to complete
      // If the promise is rejected, it will throw a $stateChangeError (see above)
      return Auth.$requireAuth();
    }]
  }
});
}]);

app.controller("HomeCtrl", ["currentAuth", function(currentAuth) {
  // currentAuth (provided by resolve) will contain the
  // authenticated user or null if not logged in
}]);

app.controller("AccountCtrl", ["currentAuth", function(currentAuth) {
  // currentAuth (provided by resolve) will contain the
  // authenticated user or null if not logged in
}]);
// for ui-router
app.run(["$rootScope", "$state", function($rootScope, $state) {
$rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
  // We can catch the error thrown when the $requireAuth promise is rejected
  // and redirect the user back to the home page
  if (error === "AUTH_REQUIRED") {
    $state.go("home");
  }
});
}]);

app.config(["$stateProvider", function ($stateProvider) {
$stateProvider
  .state("home", {
    // the rest is the same for ui-router and ngRoute...
    controller: "HomeCtrl",
    templateUrl: "views/home.html",
    resolve: {
      // controller will not be loaded until $waitForAuth resolves
      // Auth refers to our $firebaseAuth wrapper in the example above
      "currentAuth": ["Auth", function(Auth) {
        // $waitForAuth returns a promise so the resolve waits for it to complete
        return Auth.$waitForAuth();
      }]
    }
  })
  .state("account", {
    // the rest is the same for ui-router and ngRoute...
    controller: "AccountCtrl",
    templateUrl: "views/account.html",
    resolve: {
      // controller will not be loaded until $requireAuth resolves
      // Auth refers to our $firebaseAuth wrapper in the example above
      "currentAuth": ["Auth", function(Auth) {
        // $requireAuth returns a promise so the resolve waits for it to complete
        // If the promise is rejected, it will throw a $stateChangeError (see above)
        return Auth.$requireAuth();
      }]
    }
  });
}]);

app.controller("HomeCtrl", ["currentAuth", function(currentAuth) {
  // currentAuth (provided by resolve) will contain the
  // authenticated user or null if not logged in
}]);

app.controller("AccountCtrl", ["currentAuth", function(currentAuth) {
  // currentAuth (provided by resolve) will contain the
  // authenticated user or null if not logged in
}]);

Keep in mind that, even when using ng-annotate or grunt-ngmin to minify code, that these tools cannot peer inside of functions. So even though we don't need the array notation to declare our injected dependencies for our controllers, services, etc., we still need to use an array and explicitly state our dependencies for the routes, since they are inside of a function.

We have covered the three services AngularFire provides: $firebaseObject, $firebaseArray, and $firebaseAuth. In the next section we will discuss the advanced topic of extending the functionality of the $firebaseObject and $firebaseArray services.

  1. 1

    Next

    Introduction to AngularFire

  2. 2

    Next

    Synchronized Objects

  3. 3

    Next

    Synchronized Arrays

  4. 4

    Next

    User Authentication

  5. 5

    Next

    Extending the Services

  6. 6

    Next

    Beyond AngularFire