Search code examples
angularjsfirebaseangularfire

Automatically logs user in after account creation


I have an app where I am using Firebase authentication, I want to know if there is a way to:

  1. user doesn't has to log in after the creation of the account

  2. user should be logged in automatically after the account creation

This is to provide a better UX.

Here is the method I am using.

And here my code:

$scope.createUser = function(user) {
  if (user && user.email && user.name ) {
    if (user.password === user.confirm ) {
      auth.$createUser({
        name: user.name,
        email: user.email,
        password: user.password,
        confirmPass: user.confirm
      }).then(function (userData) {
        ref.child("users").child(userData.uid).set({
          name: user.name,
          email: user.email,
          displayName: user.name
        });
      }).catch(function (error) {
          console.log(error);
      });
    }
  }
};

Here the sign in function:

$scope.signIn = function (user) {
  if (user && user.email && user.pwdForLogin) {
    auth.$authWithPassword({
      email: user.email,
      password: user.pwdForLogin
    }).then(function (authData) {
      ref.child("users").child(authData.uid).once('value', function (snapshot) {
        var val = snapshot.val();
        $scope.$apply(function () {
          $rootScope.name = val;
          $scope.userDisplayInfoName = $rootScope.name.displayName;
          $scope.userDisplayInfoEmail = $rootScope.name.email;
        });
      });
    }).catch(function (error) {
        console.log(error);
    });
  }
};

Solution

  • Below is an example UserService that implements a createUser method that creates a new user, logs in that new user, and finally, binds the user's auth object to $rootScope.userData.

    User Service

    userModule.service('UserService', function($firebaseAuth, FBREF) {
      // variable to hold the currentUser's data
      var currentUser;
    
      // AngularFire authentication service
      var _authObj = $firebaseAuth(FBREF);
      
      self = {
        /**
         * `init` method that checks if a user is authenticated, and if so,
         * binds the user's auth data to `$rootScope.userData`.
         * @returns {Promise<any>} promise that resolves once auth data is bound.
         */
        init: function() {
          const auth = _authObj.$getAuth();
          // return early if there is no auth object.
          if (!auth) {
            return;
          }
    
          // create User from user factory, and get the user's data from Firebase.
          currentUser = User(auth);
    
          // return promise to bind `currentUser`'s data to `$rootScope.userData`.
          return currentUser
            .$bindTo($rootScope, 'userData')
            .then(function() {
              console.debug('Bound userData: ', currentUser);
            });
        },
    
        /**
         * `createUser` method that creates a new user with a email and password, 
         * then logs the user in with the same email and password, and finally, 
         * calls `self.init()` to bind user's auth object to `$rootScope.userData`.
         * @returns {Promise<any>} promise that resolves once the user is created,
         * `self.init` has been called, and the user's auth object is bound to
         * `$rootScope.userData` (i.e. promise from `self.init()` has resolved).
         */
        createUser: function(user, successCallback, errorCallback){
          // logout any currentUser before creating a new user
          self.logout();
    
          // first, create a new user with the email and password
          return _authObj.$createUser({
            email: user.email,
            password: user.password
          })
    
          // then, authenticate the new user with the password
          .then(function(userData) {
            return _authObj.$authWithPassword({
              email: user.email,
              password: user.password
            });
          })
          
          // finally, run any required initialization steps
          .then(function(authData) {
            self.init();
            if (successCallback && typeof successCallback === 'function') {
              successCallback();
            }
          })
          
          // catch an error if one is thrown
          .catch(function(error) {
            console.error(error);
            if (errorCallback && typeof successCallback === 'function') {
              errorCallback(error);
            }
          });
        }
      };
    
      return self;
    });
    

    Controller

    The controller implementation can then look something like this:

    userModule.controller('UserCtrl', function($scope, $state, UserService) {
      var handleSuccess = function() {
        $state.go('stateAfterSuccessfulLogin');
      };
    
      var handleError = function(error) {
        console.error(error);
      };
    
      // FIXME: simple way to check inputs have values
      var isValid = function() {
        return $scope.incomingUser.email && $scope.incomingUser.password;
      };
    
      $scope.signupWithPassword = function() {
        if (!isValid()) {
          return handleError('Missing inputs');
        }
    
        UserService.createUser($scope.incomingUser, handleSuccess, handleError);
      };
    });
    

    Resources