【问题标题】:Correct way to use firebaseAuthClient and angularJS使用 firebaseAuthClient 和 angularJS 的正确方法
【发布时间】:2013-05-07 16:36:20
【问题描述】:

一直在玩 firebase 和 angularjs,只是想把一些小东西放在一起。我现在在控制器中使用此功能在登录按钮单击时进行身份验证:

$scope.signin = function(){
        var user1 = $scope.cred.user;
        var pass1 = $scope.cred.password;

        var ref = new Firebase("https://kingpinapp.firebaseio.com");
        var auth = new FirebaseAuthClient(ref, function(error, user) {
            if (user) {
                // user authenticated with Firebase
                console.log(user);


            } else if (error) {
                 // an error occurred authenticating the user
                 console.log(error);

                } else {
                // user is logged out
            }   
        });
        auth.login('password', {
            email: user1,
            password: pass1,
            rememberMe: false
        });
        console.log("tracer");
}

现在这很棒并且工作正常。但它似乎以异步方式工作,例如我的 console.log("tracer") 在 auth.login 的用户对象之前返回。我知道我可能需要使用 Promise 来完成这项工作并尝试执行以下操作:

var defer = $q.defer();
defer.auth
.then(function() {
    auth.login('password', {
        email: user1,
        password: pass1,
        rememberMe: false
    });
})
.then(function() {
    console.log("tracer");
})

但我收到 $q 在控制器模块中声明后未定义。所以我想做的是

  1. 检查用户是否登录。
  2. 等到我收到是/否
  3. 如果未登录,请使用 auth.login
  4. 其他用户用户登录做一些其他事情

我曾想过将 auth.login 函数放在变量 auth 的 else 中,但这似乎行不通。只是试图找出正确的逻辑来理解如何让它发挥作用。

【问题讨论】:

  • new Firebase("kingpinapp.firebaseio.com") 自动返回一个承诺,当您从服务器接收数据时该承诺已解决,因此无需手动使用 $q
  • 好吧,假设我们运行 FirebaseAuthClient 来检查用户是否登录。如果没有登录,我想运行 auth.login 函数。我应该把 auth.login 放在我的 else 语句中吗?我尝试在控制台中遇到错误。
  • @asiammyself FirebaseAuthClient() 不检查用户是否登录!它只设置一个在用户的身份验证状态更改时运行的回调(请参阅:firebase.com/docs/security/simple-login-overview.html)。换句话说,在您致电auth.login() 之前,什么都不会发生。您的代码看起来是正确的,您只需将“用户登录后做一些其他事情”代码放在 if (user) { ... } 块中即可。
  • @asianmyself 顺便说一句, $q 不起作用的原因可能是因为您忘记将它注入控制器中。据我所知,Ajay 所说的并不是真的,但他说得对,如果你不想使用 $q,他是对的。
  • 因此,如果在用户身份验证发生更改时运行 FirebaseAuthClient。如果有多个控制器,而不是在每个控制器中放置一个控制器,正确的做法是将 FirebaseAuthClient 放在工厂中吗?

标签: angularjs firebase


【解决方案1】:

您不希望每个控制器都有一个 FirebaseAuthClient,但您确实希望在用户的身份验证状态发生变化时提醒所有控制器。

FirebaseAuthClient 为您处理会话存储。用户成功登录后,您只需隐藏登录屏幕/按钮。

试试这样的:

.service('myAuthService', ["$rootScope", function($rootScope) {
    var ref = new Firebase("https://kingpinapp.firebaseio.com");
    this.auth = new FirebaseAuthClient(ref, function(error, user) {
        if (user) {
            $rootScope.$emit("login", user);
        }
        else if (error) {
            $rootScope.$emit("loginError", error);
        }
        else {
            $rootScope.$emit("logout");
        }   
    });
}])
.controller('myCtrl', ["$scope", "$rootScope", "myAuthService", function($scope, $rootScope, myAuthService) {
    $scope.signin = function() {
        var user1 = $scope.cred.user;
        var pass1 = $scope.cred.password;

        myAuthService.auth.login('password', {
            email: user1,
            password: pass1,
            rememberMe: false
        });
    }
    // listen for user auth events
    $rootScope.$on("login", function(event, user) {
        // do login things
        $scope.user = user;
    })
    $rootScope.$on("loginError", function(event, error) {
        // tell the user about the error
    })
    $rootScope.$on("logout", function(event) {
        // do logout things
    })
}])
<button ng-show="user" ng-click="signin()">Sign in</button>

【讨论】:

  • 如果您能提供最简单的工作示例,我们将不胜感激 - 在此先感谢
【解决方案2】:

确保您将 $q 作为依赖项包含在您的控制器中。在简单的情况下:

function MyController($scope, $q, angularFire) {
  $scope.signin = ...
}

或者,如果您使用“正确”的模块语法:

angular.module("MyModule", ["firebase"]).
controller("MyController", ["$scope", "$q", "angularFire", function($scope, $q, aF) {
  $scope.signin = ...
}]);

在此处了解有关角度依赖注入的更多信息:http://docs.angularjs.org/guide/di,并查看https://gist.github.com/sbrekken/5151751,了解使用延迟的 Firebase 身份验证示例。

【讨论】:

  • 我正在尝试实现上述功能,但我使用的是 $routeProvider。该服务在控制器之前被触发。我已经查看了链接的延迟方法,但我无法弄清楚该代码将在哪里实现。在服务中吗?
【解决方案3】:

我已经在这里FACTORY: get current user.id for Firebase Simple Login (Email / Password)发布了这个问题的答案

这是解决这个问题的一个非常可靠的解决方案,可能正是您正在寻找的。​​p>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    相关资源
    最近更新 更多