0

I've used firebase simpleLogin with facebook in AngularJS. (Generated with angular and angularfire generators in yeoman)

How do I keep the user in a variable, $scope, $rootScope etc. correctly? The user is going to be used in another angular module.

The code looks like this:

'use strict';
angular.module('angularfire.login', ['firebase', 'angularfire.firebase'])

  .run(function(simpleLogin) {
    simpleLogin.init();
  })

  .factory('simpleLogin', function($rootScope, $firebaseSimpleLogin, firebaseRef, $timeout) {
    function assertAuth() {
      if( auth === null ) { throw new Error('Must call loginService.init() before using its methods'); }
    }

    var auth = null;
    return {
      init: function() {
        auth = $firebaseSimpleLogin(firebaseRef());
        return auth;
      },

      logout: function() {
        assertAuth();
        auth.$logout();
      },

      /**
       * @param {string} provider
       * @param {Function} [callback]
       * @returns {*}
       */
      login: function(provider, callback) {
        assertAuth();
        auth.$login(provider, {rememberMe: true}).then(function(user) {
          if( callback ) {
            //todo-bug https://github.com/firebase/angularFire/issues/199
            $timeout(function() {
              callback(null, user);
            });
          }
        }, callback);

      }
    };
  });

For instance $rootScope.user = user; is working, but I've been told that's not a clean method. Also, if I'm refreshing I'm stilled logged in, but the $rootscope.user becomes undefined.

Thanks

3 Answers 3

3

The best way is to directly assign the object returned by $firebaseSimpeLogin to $scope:

$scope.auth = $firebaseSimpleLogin(firebaseRef());

You can then reference this in your views directly. For example:

<span ng-show="auth.user">
  {{auth.user.name}} | <a href="#" ng-click="auth.$logout()">Logout</a>
</span>
<a href="#" ng-hide="auth.user" ng-click="auth.$login('facebook')">Login</a>
Sign up to request clarification or add additional context in comments.

2 Comments

If I take $scope as an dependency in the function (along with $rootScope, $firebaseSimpleLogin, firebaseRef, $timeout), the view won't render for some reason. But it works fine with $rootScope.auth = auth; Do you think that is an ok solution?
That seems like a bug, why should the view not render when you include $scope? It's cleaner to use $scope rather than $rootScope.
0

Meant to be a comment for the question on Anant's answer but require 50 rep to comment:

$scopes in AngularJS are arranged in a hierarchical structure that mimics the DOM so they are nestable.

Comments

0

The problem is that when you reload, the authenticated user won't become available until the application has talked to the FireBase server. Thankfully, FireBase will trigger an event when this is done and you can capture that event to push your user information to the $scope or $rootScope.

 $rootScope.$on('$firebaseSimpleLogin:login', function (e, authUser) {
    var ref = new Firebase(FIREBASE_URL + '/users/' + authUser.uid);
    var user = $firebase(ref).$asObject();

    user.$loaded().then(function() {
      $rootScope.currentUser = user;
    });

    $location.path('/meetings');
  });

I personally don't have a problem with storing the current user's info on the $rootScope. It's not very much data and you would probably have to feed it into the scope on every page...and that's exactly what $rootScope is for.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.