Angularfire tutorial on thinkster io login status not updated

315 Views Asked by At

I am following the AngularFire tutorial on thinkster. The $simpleLogin service has been deprecate, so I changed some of the code.

The factory:

app.factory('Auth', function ($firebaseSimpleLogin, FIREBASE_URL, $rootScope, $location){
var ref = new Firebase(FIREBASE_URL);
var Auth = { 
    register = function(){
        //...
    },
    resolveUser = function(){
        //...
    },
    signedIn = function(){
        var authData = ref.getAuth();
        if (authData) {
            console.log("User is signed in");
            return true;
        } else {
            console.log("User is not signed in");                
            return false;
        }
    }

The controller:

app.controller('NavCtrl', ['$scope', '$location', 'Post', 'Auth', function ($scope, $location, Post, Auth){
    $scope.post = {url: 'http://', title: ''};

    $scope.submitPost = function (){
        Post.create($scope.post).then(function (ref){
            $location.path('/posts/' + ref.name());
            $scope.post = {url: 'http://', title: ''};
        })
    };

    $scope.signedIn = Auth.signedIn();
    $scope.logout = Auth.logout;
}]);

app.config(function($routeProvider){
$routeProvider
  .when('/', {
    templateUrl: 'views/posts.html',
    controller: 'PostsCtrl'
  })
  .when('/posts/:postId', {
    templateUrl: 'views/showpost.html',
    controller: 'PostViewCtrl'
  })
  .when('/register', {
    templateUrl: 'views/register.html',
    controller: 'AuthCtrl',
    resolve: {
        user: function(Auth){
            return Auth.signedIn();
        }
    }
  })
  .when('/login', {
    templateUrl: 'views/login.html',
    controller: 'AuthCtrl',
    resolve: {
        signedIn: function(Auth){
            return Auth.signedIn();
        }
    }
  })
  .otherwise({
    redirectTo: '/'
  });                

Relevant part of the template:

    <ul class="nav navbar-nav navbar-right">
  <li ng-show="signedIn">
    <a ng-href="#" ng-click="logout()">Logout</a>       
  </li>
  <li ng-hide="signedIn">
    <a href="#/register">Register</a>
  </li>
  <li ng-hide="signedIn">
    <a href="#/login">Login</a>
  </li>

The problem is the signedIn variable doesn't get updated when I login in, so the register and Login links are still visible to the user while the logout link is not shown.

2

There are 2 best solutions below

0
user2901633 On BEST ANSWER

Finally figure out a solution,

In the controller:

  $scope.auth = Auth.auth();
  $scope.auth.$onAuth(function(authData){
    $timeout(function(){
        $scope.user = authData;
    });
  });

In the factory:

  var ref = new Firebase(FIREBASE_URL);
  var auth = $firebaseAuth(ref);
  var Auth = {
        auth: function(){
            return auth;
        }
      }

  Return Auth;

So I think it's the $timeout that makes the difference?

1
Frank van Puffelen On

You controller sets signedIn as follows:

$scope.signedIn = Auth.signedIn();

When the controller is initialized, this code executes and the scope variable is set only once.

If you look in the Firebase documentation for monitoring authentication state, you will find this example just above the one you seem to have started with:

ref.onAuth(function(authData) {
  if (authData) {
    // user authenticated with Firebase
    console.log("User ID: " + authData.uid + ", Provider: " + authData.provider);
  } else {
    // user is logged out
  }
});

Where your snippet checks (using getAuth) whether the user is currently logged in, this monitors the referenced Firebase (using onAuth) until a user logs in. At that point you can set/update your property in the scope and notify AngularJS of the change:

$scope.signedIn = !!ref.getAuth(); // true if the user is already logged in
ref.onAuth(function(authData) {
    $scope.signedIn = !!ref.getAuth(); 
    $scope.$apply();
});

In case you are already using AngularFire, you can simply use the $firebaseAuth service that comes with it and accomplish the same: https://www.firebase.com/docs/web/libraries/angular/guide.html#section-angular-authentication