0

当我使用 时".read": "auth != null",在无错误完成ref.on()后引发权限ref.auth()错误。只要用户登录,授予读取权限的正确方法是什么?

安全规则:

{
  "rules": { 
    ".read": "auth != null",
    ".write": "auth.admin == true"
  }
}

这是在我对其执行“on()”之前返回给我 Firebase ref 的代码:

    ref: function(path) { var self = this;
      var ref = new Firebase(self.url + path);
      ref.auth(self.auth_token, function(err) {
        if (err && console) console.log("Firebase "+path+" login failed!");
        else if (console) console.log("Firebase "+path+" login succeeded.");
      });
      return ref;
    },
    bind: function(path, excludes) { var self = this;
      var collection = [];
      var ref = self.ref(path);
      ...
      var move_callback = function(data, prevId) { 
        $timeout(function() { moveItem(data, prevId); }); 
      }
      ref.on('child_added', move_callback);
      ref.on('child_changed', move_callback);
      ref.on('child_moved', move_callback);
      ref.on('child_removed', function(data) {
        $timeout(function() { removeItem(data); });
      });
      return collection;
    },

主控制器:

$scope.list = $$firebase.bind("/data", []);

控制台说

Firebase /data login succeeded. app.js:298
FIREBASE WARNING: on() or once() for /data failed: permission_denied firebase.js:33
4

1 回答 1

2

从您的代码中我不清楚您在身份验证完成后返回参考。具体来说:

ref: function(path) {
  var self = this;
  var ref = new Firebase(self.url + path);
  ref.auth(self.auth_token, function(err) {
    if (err && console) console.log("Firebase "+path+" login failed!");
    else if (console) console.log("Firebase "+path+" login succeeded.");
  });
  return ref;
}

立即返回引用。auth 的回调是异步的,因此如果您在调用回调之前使用您的 ref,您的会话将未经身份验证。

看起来您正在使用 Angular,所以我制作了一个小示例,它使用与您相同的安全规则正常工作:https ://gist.github.com/anantn/5304404

如果我要重写你的代码,我会这样做:

bind: function(path) {
  var ref = new Firebase(self.url + path);
  var d = self._q.defer(); // Assign $q to this._q in constructor.
  ref.auth(self.auth_token, function(err) {
    if (!err) {
      ref.once("value", function(snap) {
        d.resolve(snap.val());
      });
    }
  });
  return d.promise;
}
...
// In the controller:
$scope.list = $$firebase.bind("/data");

我强烈建议通过 $q 模块使用 Promise,以确保您在身份验证完成之前不使用 Firebase 引用。更好的解决方案是使用 Angular 的官方 Firebase 绑定,它已经为您处理了所有这些:https ://github.com/firebase/angularFire

希望这可以帮助!

于 2013-04-03T19:29:15.237 回答