Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Routes and Resolve with new Firebase Auth

Tags:

I am trying to use the new Firebase with the Auth system and restricting routes in my $routeProvider via resolves.

However, I'm not quite understanding.

This is what I have. In my .config function, I am defining routes and initializing firebase. The following is in my config block.

$routeProvider
   .when('/', {
      templateUrl: 'templates/dashboard.ejs',
      //resolve. this needs restricted
   })
   .when('/login', {
      templateUrl: 'templates/login.ejs'
   })

firebase.initializeApp(config);

I have found on the new docs site that these functions are available that are listed in my .run() block for angular.

.run(function($rootScope, $location) {

    $rootScope.authentication = firebase.auth();

    /*firebase.auth().onAuthStateChanged(function(user) {
        if(user) {
            $rootScope.user = user;
        } else {
            $rootScope.user = false;
            $location.path('/login')
        }
    })*/

    var user = firebase.auth().currentUser;

    if (user) {
        $rootScope.user = user;
    } else {
        $rootScope.user = false;
        console.log('No User!');
        $location.path('/login');
    }
})

Now, what I have above is only firing every other time I access any url on my site.

So my question is, how do I take what's in my .run() function and make it into a resolve for my routeProvider so I'm able to restrict routes again.

With the old firebase you would just call $firebaseAuth() like below and have a routeChangeError function that was called like the following.

// In config block. **old way**
$routeProvider
        .when('/', {
            templateUrl: 'templates/dashboard.ejs',
            resolve: {
                "currentAuth": ["$firebaseAuth", function($firebaseAuth) {
                    var ref = new Firebase(fbUrl);
                    var authObj = $firebaseAuth(ref);

                    return authObj.$requireAuth();
                }]
            }
        })

And then the routechangeerror in the .run() block.

 // .run block **old way**
 .run(function($rootScope, $location) {
    $rootScope.$on("$routeChangeError", function(event, current, previous, eventObj) {
        if (eventObj === 'AUTH_REQUIRED') {
            console.log('auth required!');
            $location.path("/login");
        }
    });
})

This doesn't work anymore because you aren't using $firebaseAuth() anymore. or new Firebase(fbUrl); for that matter either.

UPDATE

I feel like it's a bit messy but looking into routes a little more, I came up with this.

In my route resolve:

.when('/', {
            templateUrl: 'templates/dashboard.ejs',
            resolve: {
                userAuthenticated: ["$http", "$q", function($http, $q) {
                    var deferred = $q;
                    if(firebase.auth().currentUser) {
                        deferred.resolve();
                    } else {
                        deferred.reject();
                        console.log('Really!?');
                    }
                    return deferred.promise;
                }]
            }
        })  

And then a simple routeChangeError.

$rootScope.$on("$routeChangeError", function (event, current, previous, rejection) {
        alert("Not authorised");
})

The only problem is, it appears the deferred.promise is returning undefined. It's not activating the routeChangeError function. Even though my console.log() is getting called.

Could this be because firebase.auth().currentUser returns null when no user is authenticated?

like image 786
Mitch Evans Avatar asked Jun 08 '16 01:06

Mitch Evans


1 Answers

The methods have been renamed to $waitForSignIn() and $requireSignIn.

You can also use the $firebaseRefProvider service to configure your Database URL so it automatically configures the $firebaseAuthService.

angular.module('app', ['firebase'])
  .constant('FirebaseDatabaseUrl', '<my-firebase-url>')
  .controller('HomeCtrl', HomeController)
  .config(function($firebaseRefProvider, FirebaseDatabaseUrl, $routeProvider) {
     $firebaseRefProvider.registerUrl(FirebaseDatabaseUrl);
     $routeProvider.when("/home", {
        controller: "HomeCtrl",
        templateUrl: "views/home.html",
        resolve: {
          // controller will not be loaded until $waitForSignIn resolves
          "firebaseUser": function($firebaseAuthService) {
            return $firebaseAuthService.$waitForSignIn();
          }
        }
      }).when("/account", {
        controller: "AccountCtrl",
        templateUrl: "views/account.html",
        resolve: {
          // controller will not be loaded until $requireSignIn resolves
          "firebaseUser": function(Auth) {
            // If the promise is rejected, it will throw a $stateChangeError
            return $firebaseAuthService.$requireSignIn();
          }
        }
      });
  });

function HomeController($scope, $firebaseRef, firebaseUser) {

} 
like image 133
David East Avatar answered Oct 20 '22 11:10

David East