问题
I am trying to anonymously authenticate users using AngularFire. I want to authenticate a user only once (so, if the user has already been authenticated, a new uid won't be generated). When I use the code below, I get a previous_websocket_failure
notification. I also get an error in the console that says TypeError: Cannot read property 'uid' of null
. When the page is refreshed, everything works fine.
Any thoughts on what I'm doing wrong here?
app.factory('Ref', ['$window', 'fbURL', function($window, fbURL) {
'use strict';
return new Firebase(fbURL);
}]);
app.service('Auth', ['$q', '$firebaseAuth', 'Ref', function ($q, $firebaseAuth, Ref) {
var auth = $firebaseAuth(Ref);
var authData = Ref.getAuth();
console.log(authData);
if (authData) {
console.log('already logged in with ' + authData.uid);
} else {
auth.$authAnonymously({rememberMe: true}).then(function() {
console.log('authenticated');
}).catch(function(error) {
console.log('error');
});
}
}]);
app.factory('Projects', ['$firebaseArray', '$q', 'fbURL', 'Auth', 'Ref', function($firebaseArray, $q, fbURL, Auth, Ref) {
var authData = Ref.getAuth();
var ref = new Firebase(fbURL + '/projects/' + authData.uid);
console.log('authData.uid: ' + authData.uid);
return $firebaseArray(ref);
}]);
回答1:
In your Projects factory, you have assumed authData
will not be null. There are no guarantees here, since your Projects factory is initialized as soon as you inject it into another provider. I also noticed that your Auth service doesn't actually return anything. This probably means that the caller has to know the internal workings and leads to quite a bit of coupling. A more SOLID structure would probably be as follows:
app.factory('Projects', function(Ref, $firebaseArray) {
// return a function which can be invoked once
// auth is resolved
return function(uid) {
return $firebaseArray(Ref.child('projects').child(uid));
}
});
app.factory('Auth', function(Ref, $firebaseAuth) {
return $firebaseAuth(Ref);
});
app.controller('Example', function($scope, Auth, Projects) {
if( Auth.$getAuth() === null ) {
auth.$authAnonymously({rememberMe: true}).then(init)
.catch(function(error) {
console.log('error');
});
}
else {
init(Auth.$getAuth());
}
function init(authData) {
// when auth resolves, add projects to the scope
$scope.projects = Projects(authData.uid);
}
});
Note that dealing with auth in your controllers and services should generally be discouraged and dealing with this at the router level is a more elegant solution. I'd highly recommend investing in this approach. Check out angularFire-seed for some example code.
来源:https://stackoverflow.com/questions/30279725/getting-websocket-failure-when-trying-to-anonymously-authenticate-user-using-ang