我尝试在将用户保存在firebase用户表中之前检查用户,但是当我使用.once()firebase方法检查时,该函数始终返回false ...
当我在函数内部使用console.log时,它会正确记录,但它永远不会返回true。
Auth代表基本的Firebase Auth Factory
var newUser = function(id) {
ref.child('users').child(id).once('value', function(snapshot) {
console.log(snapshot.val() === null);
return (snapshot.val() === null);
});
};
Auth.$onAuth(function(authData) {
console.log(Boolean(newUser(authData.uid)));
if (authData && !!(newUser(authData.uid))) { // add user if first time login
$scope.authData = authData;
ref.child('users').child(authData.uid).$save({
provider: authData.uid,
name: getName(authData),
blah: 'blah'
});
$state.go('main.home');
} else if (authData) {
$state.go('main.home');
} else {
console.log('Not Logged In');
}
});
答案 0 :(得分:0)
您的新用户功能无法返回任何内容。也许它会帮助你看看你是否将你的回调函数移到它自己的命名函数中。
var onValue = function(snapshot) {
console.log(snapshot.val() === null);
return (snapshot.val() === null);
};
var newUser = function(id) {
ref.child('users').child(id).once('value', onValue);
// new user doesn't return anything
};
当你省略一个返回值时,该函数会自动返回undefined
,你正在强制转换为布尔值 - 产生false
。
这里的问题是Firebase的.once
方法的回调在您的函数(未能)返回值之后运行。这是因为它是异步的。
对于新的Javascript开发人员来说,这是一个相当普遍的问题,但可以通过一个小例子轻松实现。
function doAsync() {
setTimeout(function() {
console.log('a');
return 'a';
}, 3000);
console.log('b');
return 'b';
}
doAsync();
您期望console.log
语句运行的顺序是什么?您希望函数返回哪个值?如果不是很明显,请花些时间在您的控制台中尝试代码。
显然,能够从异步函数中获取值仍然很重要。一种方法是使用回调函数。
在您的情况下,您需要为新用户功能添加一个回调参数,然后在新用户可用时立即调用该功能。
var newUser = function(id, done) {
ref.child('users').child(id).once('value', function(snapshot) {
done(snapshot.val() === null);
});
};
然后修改您的其他代码以使用此样式。
Auth.$onAuth(function(authData) {
newUser(authData.uid, function(val) {
// do something with the result
});
});