在Firebase 3.x中从控制器获取firebase.User的明显竞争条件

时间:2016-06-27 12:52:12

标签: angularjs firebase firebase-authentication

我使用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,但是在我的控制器准备好之前,这还没有初始化。如何在我开始在我的应用中路由之前获取当前登录的用户以使其可用?

1 个答案:

答案 0 :(得分:1)

我建议直接在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')无论如何都是异步解析,它只会为方法添加一些延迟,但不会改变它的行为。

使用此“一次性”观察者模式(第一次调用其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;
      });
  });
};