从 Firebase 3.x 中的控制器获取 firebase.User 的明显竞争条件
Apparent race condition getting firebase.User from controller in Firebase 3.x
我正在使用 Firebase 3.x 和身份验证状态更改事件来分配我服务中的当前用户 -
.service('FireService', 函数 ($q, $http,$state) {
var accessToken;
var user;
firebase.auth().onAuthStateChanged(function (usr) {
if (usr) {
// User signed in!
user = usr;
} else {
user = null;
$state.go('login');
}
});
return {
currentUser: function () {
return user;
}
}
但我需要当前用户从控制器中的数据库中引用我的子对象
var getLog = function () {
var logRange = currentDate.format('MMMYYYY').toUpperCase();
var userId = FireService.currentUser().uid;
var ref = LogService.logs(userid,logRange);
// download the data into a local object
ref.once('value').then(
function (result) {
logObj = result;
})
};
当我设置断点时,我看到 currentUser() 始终为空,因为状态更改尚未触发。我也尝试过直接从 firebase.User 分配我的用户 ID,但是当我的控制器准备好时,它还没有初始化。如何获取当前登录的用户,以便在我开始在我的应用程序中进行路由之前可用?
我建议直接在 getLog
方法中使用观察者,这样它会等到当前用户被设置:
var getLog = function () {
var unsubscribe = firebase.auth().onAuthStateChanged(function(user) {
if (user) {
var logRange = currentDate.format('MMMYYYY').toUpperCase();
var userId = user.uid;
var ref = LogService.logs(userid,logRange);
// download the data into a local object
ref.once('value').then(
function (result) {
logObj = result;
});
}
unsubscribe(); // So this observer is only triggered once.
});
};
由于 ref.once('value')
无论如何都是异步解析的,它只会给方法增加一点延迟,但不会改变其行为。
使用此 "one off" 观察者模式(第一次调用其 unsubscribe
函数的观察者)允许您确保 Firebase Auth在执行代码之前完全初始化。如果在您创建观察者时 Firebase Auth 已经初始化,那么它的解析将立即被触发。请记住,观察者总是被异步调用。
如果您最终经常使用这种模式,您可以在 FireService 上添加一个方法:
...
ready: function() {
return $q(function(resolve, reject) {
var unsubscribe = firebase.auth().onAuthStateChanged(function(user) {
unsubscribe();
resolve(user);
});
});
}
...
并在您的 getLog
方法中使用它:
var getLog = function () {
FireService.ready().then(function(user) {
if (!user) { return; }
var logRange = currentDate.format('MMMYYYY').toUpperCase();
var userId = user.uid;
var ref = LogService.logs(userid,logRange);
// download the data into a local object
ref.once('value').then(
function (result) {
logObj = result;
});
});
};
我正在使用 Firebase 3.x 和身份验证状态更改事件来分配我服务中的当前用户 -
.service('FireService', 函数 ($q, $http,$state) {
var accessToken;
var user;
firebase.auth().onAuthStateChanged(function (usr) {
if (usr) {
// User signed in!
user = usr;
} else {
user = null;
$state.go('login');
}
});
return {
currentUser: function () {
return user;
}
}
但我需要当前用户从控制器中的数据库中引用我的子对象
var getLog = function () {
var logRange = currentDate.format('MMMYYYY').toUpperCase();
var userId = FireService.currentUser().uid;
var ref = LogService.logs(userid,logRange);
// download the data into a local object
ref.once('value').then(
function (result) {
logObj = result;
})
};
当我设置断点时,我看到 currentUser() 始终为空,因为状态更改尚未触发。我也尝试过直接从 firebase.User 分配我的用户 ID,但是当我的控制器准备好时,它还没有初始化。如何获取当前登录的用户,以便在我开始在我的应用程序中进行路由之前可用?
我建议直接在 getLog
方法中使用观察者,这样它会等到当前用户被设置:
var getLog = function () {
var unsubscribe = firebase.auth().onAuthStateChanged(function(user) {
if (user) {
var logRange = currentDate.format('MMMYYYY').toUpperCase();
var userId = user.uid;
var ref = LogService.logs(userid,logRange);
// download the data into a local object
ref.once('value').then(
function (result) {
logObj = result;
});
}
unsubscribe(); // So this observer is only triggered once.
});
};
由于 ref.once('value')
无论如何都是异步解析的,它只会给方法增加一点延迟,但不会改变其行为。
使用此 "one off" 观察者模式(第一次调用其 unsubscribe
函数的观察者)允许您确保 Firebase Auth在执行代码之前完全初始化。如果在您创建观察者时 Firebase Auth 已经初始化,那么它的解析将立即被触发。请记住,观察者总是被异步调用。
如果您最终经常使用这种模式,您可以在 FireService 上添加一个方法:
...
ready: function() {
return $q(function(resolve, reject) {
var unsubscribe = firebase.auth().onAuthStateChanged(function(user) {
unsubscribe();
resolve(user);
});
});
}
...
并在您的 getLog
方法中使用它:
var getLog = function () {
FireService.ready().then(function(user) {
if (!user) { return; }
var logRange = currentDate.format('MMMYYYY').toUpperCase();
var userId = user.uid;
var ref = LogService.logs(userid,logRange);
// download the data into a local object
ref.once('value').then(
function (result) {
logObj = result;
});
});
};