【问题标题】:How to get notified efficiently when an OAuth response is received?收到 OAuth 响应时如何有效地得到通知?
【发布时间】:2016-09-14 10:34:12
【问题描述】:

我使用ionic 和Firebase 让Facebook 和Google 登录。我有两个服务FirebaseService.js、AppService.js 和一个控制器dashboard.js。我需要在这个控制器中获得 OAuth 响应。

最好的方法是什么?我在其他几个地方遇到过这种类型的场景,因此正在寻找一种有效的方法来做到这一点。

我在其他地方使用的方法是有一个通知器(当数据可用时调用通知器)和监听器

/** notify for Auth data response */
this.authDataAvailable = function() {
    $rootScope.$emit("auth-data-available");
}
/** subscribe to this listener when the aggregated data response is available */
this.authDataAvailableListener = function(scope, callback, isDestroy) {
    var handler = $rootScope.$on("auth-data-available", callback);
    if (isDestroy)
        scope.$on("$destroy", handler);
}

/** subscribing to the above listener */
$scope.authDataResponseListener($scope, function responseAvailable() {
    //auth response available at this point
}, true);

FirebaseService.js

function FirebaseService($q) {
    this.appRef;
    this.authData; //.provider: ["facebook"||"google"], facebook.displayName || google.displayName, facebook.id || google.id, facebook.profileImageURL || google.profileImageURL

    this.getRef = function() {
        return this.appRef;
    }
    this.authWithOAuthPopup = function(type) {
        var deferred = $q.defer();
        this.appRef = new Firebase("https://lola.firebaseio.com");
        this.appRef.authWithOAuthPopup(type, function(error, authData) {
            if (error) {
                this.authError = error;
                switch (error.code) {
                    case "INVALID_EMAIL":
                        console.log("The specified user account email is invalid.");
                        break;
                    case "INVALID_PASSWORD":
                        console.log("The specified user account password is incorrect.");
                        break;
                    case "INVALID_USER":
                        console.log("The specified user account does not exist.");
                        break;
                    default:
                        console.log("Error logging user in:", error);
                }
                deferred.resolve(this.authError);
            } else {
                this.authData = authData;
                console.log("Authenticated successfully with payload:", authData);
                deferred.resolve(this.authData);
            }
        });
                deferred.promise;
    }

    /**
     * Write or replace data to a defined path, like messages/users/<username>
     */
    this.set = function(child, obj) {
        var childRef = this.appRef.child(child);
        childRef.set(obj);
    }

    return {
        getRef: this.getRef,
        authWithOAuthPopup: this.authWithOAuthPopup
    }
}
angular.module("starter.services", []).service('FirebaseService', FirebaseService);

AppService.js

function AppService(FirebaseService, $rootScope) {
    this.authData; //.provider: ["facebook"||"google"], facebook.displayName || google.displayName, facebook.id || google.id, facebook.profileImageURL || google.profileImageURL

    /** notify for Auth data response */
    this.authDataAvailable = function() {
        $rootScope.$emit("auth-data-available");
    }
    /** subscribe to this listener when the aggregated data response is available */
    this.authDataAvailableListener = function() {
        var handler = $rootScope.$on("auth-data-response", callback);
        if (isDestroy)
            scope.$on("$destroy", handler);
    }

    this.authenticateWithGoogle = function() {
        this.authData = FirebaseService.authWithOAuthPopup("google");
        this.authDataAvailable();
        console.log(this.authData.google.displayName);
    }

    this.authenticateWithFacebook = function() {
        this.authData = FirebaseService.authWithOAuthPopup("facebook");
        this.authDataAvailable();
        console.log(this.authData.facebook.displayName);
    }

    this.getAuthData = function() {
        return this.authData;
    }

    return {
        authenticateWithGoogle: this.authenticateWithGoogle,
        authenticateWithFacebook: this.authenticateWithFacebook,
        getAuthData: this.getAuthData            
    }
}

angular.module('starter.services').service('AppService', AppService);

dashboard.js

function DashCtrl($scope, AppService) {
    $scope.user = "";
    $scope.openBrowser = function() {
        AppService.authenticateWithFacebook();
        /*var authData = AppService.getAuthData();
        $scope.user = authData.facebook.displayName;
        console.log(authData);
        console.log($scope.user);*/
    }
}

angular.module("starter.controllers", []).controller('DashCtrl', DashCtrl);

在我的方法中,AppService.js 语句 this.authDataAvailable(); 在 this.authenticateWithFacebook 函数下出现 this.authDataAvailable is not a function 错误。

请帮助我了解实现此类场景的有效方法或最佳实践。

更新

因此,在 mJunaidSalaat 的帮助下,我遇到了 2 件有助于解决我的问题的事情。

  1. 在我的 AppService.js 中使用类似下面的内容

    this.authenticateWithFacebook = function() {
        FirebaseService.authWithOAuthPopup("facebook")
        .then(function(data) {
            service.authData = data;
            console.log(this.authData);
            service.authDataAvailable();
            console.log(this.authData.facebook.displayName);
        }, function(err) {
            console.log(err)
        });
     }
    
  2. 在任何外壳内使用this 的标识符会更改上下文。所以在我的情况下使用service。

【问题讨论】:

  • 在this.authenticateWithFacebook函数中你收到this.authData吗?我的意思是尝试像console.log(this.authData) 一样记录它
  • @mJunaidSalaat: 不,我在this.authenticateWithFacebook 函数中得到undefined for console.log(this.authData);

标签: javascript angularjs oauth ionic-framework firebase


【解决方案1】:

在FirebaseService.js 中,回调函数没有返回接收到的数据承诺。尝试添加

this.authWithOAuthPopup = function(type) {
        var deferred = $q.defer();
        this.appRef = new Firebase("https://lola.firebaseio.com");
        this.appRef.authWithOAuthPopup(type, function(error, authData) {
            if (error) {
                this.authError = error;
                switch (error.code) {
                    case "INVALID_EMAIL":
                        console.log("The specified user account email is invalid.");
                        break;
                    case "INVALID_PASSWORD":
                        console.log("The specified user account password is incorrect.");
                        break;
                    case "INVALID_USER":
                        console.log("The specified user account does not exist.");
                        break;
                    default:
                        console.log("Error logging user in:", error);
                }
                deferred.resolve(this.authError);
            } else {
                this.authData = authData;
                console.log("Authenticated successfully with payload:", authData);
                deferred.resolve(this.authData);
            }
        });
        return defered.promise;//this returns the promise rejected or resolve with the supplied data
    }

在AppService.js 中处理承诺

this.authenticateWithFacebook = function() {
        var service = this;
        FirebaseService.authWithOAuthPopup("facebook")
          .then(function(data){
            this.authData = data
            console.log(this.authData.facebook.displayName);
            service.authDataAvailable();
          },function(err){
              console.log(err)
          });
    }

希望对你有帮助。

【讨论】:

  • 我在});之后添加了return deferred.promise;,它返回一个空的承诺,状态为0。我也在更新m问题。
  • 是的,对不起,这是我的错误。更正了它。谢谢
  • @Ricky 告诉我一个。你的console.log("Authenticated successfully with payload:", authData); 记录了什么?你在这里得到authData 对象吗?
  • 我收到 Authenticated successfully with payload: Object {provider: "facebook", uid: "facebook:1324428977082662", facebook: Object, token: "eyJ0eXAiOyJKV4QiLJhbGciOiJIUzI1NiJ9.eyJwcm92aWRlc…sifX0.Re0LR7EzhX1VpqsnM1-z31mjHynEt4cqthZ8DjkGE90", auth: Object…} 但无法在 this.authenticateWithFacebook 函数中获取此信息。 ionic.bundle.js:26771 TypeError: this.authDataAvailable is not a function 错误仍然存​​在
  • 你试过我编辑的答案了吗?而错误ionic.bundle.js:26771 TypeError: this.authDataAvailable is not a function cAme 紧随其后?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多