I have a loginService factory used to perform login, logout and provide user data to controllers. Because I need to update userdata in controllers every time loginstate changes, my factory method is returning an update promise:
app.controller('TestCtrl', function ($scope, loginService) {
loginService.currentUserData().then(null, null, function(CurrUserData){
$scope.CurrUserData = CurrUserData;
});
});
In loginService I'm listening to $firebaseSimpleLogin:login/logout events and after they're fired, I pass the userdata object (returned by function based on UID) or null ($fbSimpleLogin:logout event) to $emit. And finally, in my loginService.currentUserData() method I'm listening to this emitted events and returning deferred.notify(userdata/null).
First issue is that when I change the view (template+ctrl+location), I need to invoke $firebaseSimpleLogin:login/logout event to deliver my userData to new controller. Now, I'm doing it by $locationChangeStart event, but there should be better way...
And last issue: when I'm changing the view, there are more data calls, than I expectet. Probably every controller add event listeners on $rootScope by calling loginService.currentUserData()? Described code below:
$rootScope.$on('$firebaseSimpleLogin:login', function (e, authUser) {
findUserByUid(authUser.uid);
});
$rootScope.$on('$firebaseSimpleLogin:logout', function() {
$rootScope.$emit('userLogout', null);
});
$rootScope.$on('$locationChangeStart', function(event, next, current) {
currentUser().then(function(u){
$timeout(function() { // without this same event on viewchange is fired
// by simplelogin, collision (I need to replace this whole block with invoking simpleloginevent)
if (u) {$rootScope.$emit('$firebaseSimpleLogin:login', u);
} else {$rootScope.$emit('$firebaseSimpleLogin:logout', null);};
}, 150);
});
});
function findUserByUid (uid) {
var query = $firebase(usersRef.startAt(uid).endAt(uid));
query.$on('loaded', function () {
var username = query.$getIndex()[0];
setCurrentUser(username);
});
}
function setCurrentUser (username) {
if (username) {$rootScope.$emit('userData', $firebase(usersRef).$child(username));};
}
var currentUserData = function () { // this method is used in CTRLs
var deferred = $q.defer();
var uDl = $rootScope.$on('userData', function(e, FbUserData){deferred.notify(FbUserData); });
var uLl = $rootScope.$on('userLogout', function(){deferred.notify(null); });
return deferred.promise;
};
I recently wrote a demo AngularFire app that has similar functionality. The way I found to handle this is only worry about three points.
When the user logs in $rootScope.$on('$firebaseSimpleLogin:$login')
When the user logs out $rootScope.$on('$firebaseSimpleLogin:$logout')
Calling $getCurrentUser()
This will be able to capture the login life cycle. Since you need to know who the current user is, you can rely on the $firebaseSimpleLogin method rather than trying to $emit your own events.
You also could resolve the current user in the $routeProvider for each view. This way each view won't be rendered until the user has been loaded.
Here's the plunker project and the example Factory: http://plnkr.co/edit/M0UJmm?p=preview
// Auth factory that encapsulates $firebaseSimpleLogin methods
// provides easy use of capturing events that were emitted
// on the $rootScope when users login and out
.factory('Auth', function($firebaseSimpleLogin, Fb, $rootScope) {
var simpleLogin = $firebaseSimpleLogin(Fb);
return {
getCurrentUser: function() {
return simpleLogin.$getCurrentUser();
},
login: function(provider, user) {
simpleLogin.$login(provider, {
email: user.email,
password: user.password
});
},
logout: function() {
simpleLogin.$logout();
},
onLogin: function(cb) {
$rootScope.$on('$firebaseSimpleLogin:login',
function(e, user) {
cb(e, user);
});
},
onLogout: function(cb) {
$rootScope.$on('$firebaseSimpleLogin:logout',
function(e, user) {
cb(e, user);
});
}
}
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.