AngularFire2登录注销订阅Auth问题 - Angular2

Cod*_*het 9 authentication angularfire2 angular

好吧,所以我一直在撞墙直到半天试图解决这个问题,因为我还没有因为我的知识水平AngularFire2而且Angular2有点初学者.

我有一个应用程序,它使用一个简单的登录表单AngularFire2所连接到Facebook,检索用户Access TokenFacebook Id,然后调用Facebook Graph API返回名字,姓氏,性别,电子邮件等.

如下图所示:

loginWithFacebook(): FirebaseListObservable<string> {

    return FirebaseListObservable.create(obs => {
        this.af.auth.login({
            provider: AuthProviders.Facebook,
            method: AuthMethods.Popup,
            scope: ['public_profile']
        }).then((authState: any) => {

            let authSubscription = this.af.auth.subscribe(auth => {

             if (auth == null) return;

                let url = `https://graph.facebook.com/v2.8/${auth.facebook.uid}?fields=first_name,last_name,gender,email&access_token=${authState.facebook.accessToken}`;

                this.http.get(url).subscribe(response => {
                    let user = response.json()

                    this.af.database.object('/users/' + authState.uid).update({
                        first_name: user.first_name,
                        last_name: user.last_name,
                        display_name: auth.facebook.displayName,
                        gender: user.gender,
                        email_address: auth.facebook.email,
                        accessToken: authState.facebook.accessToken,
                        facebook_Id: auth.facebook.uid,
                    })
                },
                    err => {
                        obs.next(false);
                    });

            });

            authSubscription.unsubscribe();

            obs.next(true);

        }).catch(err => {
            obs.next(false);
        });
    });

}
Run Code Online (Sandbox Code Playgroud)

Facebook Id=来自auth Access Token=来自authState

我然后保存在返回的信息Facebook Graph APIFirebase.

现在问题来了,正如你在上面指定的函数中看到的那样,我已经订阅了这个auth方法,这允许我访问Facebook IdAccess Token调用所需的函数Facebook Graph API

在我的应用程序导航中,我有一个注销按钮.当用户点击此按钮时,我会打电话

this.af.auth.logout();
Run Code Online (Sandbox Code Playgroud)

一旦我按下注销,我的上面指定的函数将被调用,因为订阅了更改auth,我在里面放了一个if语句来检查auth是否为null,如果是这样返回哪个工作 - 看起来有点hacky到我.

如果我然后尝试重新登录,则调用的URL会因为状态而Facebook Graph API失败,我不完全确定为什么会失败,因为对我来说它被归类为新登录,因此该方法应该从头到尾再次运行.${auth.facebook.uid}undefined

现在我的问题是:

如何auth在我的Login with facebook方法中订阅?并仍然访问Facebook IdAccess Token

我试图找出一种方法,该方法将适用于两种情况:

  1. 用户已存在于数据库中
  2. 用户不存在,所以它是一个新的注册.

注销和注册/登录都应彼此隔离,不要干扰彼此的职责.

如果任何人都可以分享任何知识或建议更清洁的方式这样做,我将非常感激.

更新

我已经创建了一个存储库,Github它是我的应用程序的简化版本,它显示了我遇到的错误.

回购

复制:

login.serviceloginWithFacebook方法中,您将看到以下代码行:

if (auth.facebook.uid == null) return;
Run Code Online (Sandbox Code Playgroud)

对此进行评论并按照以下步骤操作.

  1. 在注册页面上登录facebook
  2. 使用注销按钮注销
  3. 退出后直接用facebook重新登录

您将注意到第一次登录时,只要您注销并使用Facebook重新登录,图形API将因auth.facebook.uid未定义而失败.

现在理想情况下我不想订阅auth事件的原因是因为我们将使用Google和电子邮件和密码实现登录.

我想订阅auth活动的唯一地方是导航栏内部,当用户获得授权时,它会更改菜单导航.

注意:这与firebase上的测试帐户相关联.解决此问题后,将删除测试帐户.因此,将删除用于测试此信息的所有帐户信息.

最后更新

好的,所以我决定打开这个奖金以帮助找到解决方案.

我能看到这个工作的唯一方法是有一个登录页面,这个登录页面将迎合新用户和现有用户,如果用户是新用户登录,那么请调用Facebook Graph API检索有关他们的信息,然后保存,如果他们存在,那么不要调用Facebook Graph API.

我希望如何工作:

新用户:

1.  User navigates to website
2.  Signs in with Facebook
3.  Popup appears
4.  Users grants the permissions I’ve requested
5.  Callback to website <- at this point I have access to users Facebook Id and accessToken via the auth
6.  Call Facebook Graph API retrieve first_name, last name etc passing in users Facebook Id and accessToken
7.  Then save the information returned from Facebook Graph to Firebase
Run Code Online (Sandbox Code Playgroud)

现有用户

如果用户已经使用Facebook注册,那么当他/她登录时我不想调用Facebook Graph API时,对于新帐户只需要调用一次图表.

回购仍然可用.

在首次注册,注销,登录后,错误打印到控制台:

在此输入图像描述

AngularFire2包json

{
  "_args": [
    [
      {
        "raw": "angularfire2@^2.0.0-beta.7",
        "scope": null,
        "escapedName": "angularfire2",
        "name": "angularfire2",
        "rawSpec": "^2.0.0-beta.7",
        "spec": ">=2.0.0-beta.7 <3.0.0",
        "type": "range"
      },
      "/Users/Scott/Desktop/test-application-master 2"
    ]
  ],
  "_from": "angularfire2@>=2.0.0-beta.7 <3.0.0",
  "_id": "angularfire2@2.0.0-beta.7",
  "_inCache": true,
  "_location": "/angularfire2",
  "_nodeVersion": "6.9.1",
  "_npmOperationalInternal": {
    "host": "packages-12-west.internal.npmjs.com",
    "tmp": "tmp/angularfire2-2.0.0-beta.7.tgz_1484315670561_0.09154823864810169"
  },
  "_npmUser": {
    "name": "davideast",
    "email": "dceast@gmail.com"
  },
  "_npmVersion": "3.10.8",
  "_phantomChildren": {},
  "_requested": {
    "raw": "angularfire2@^2.0.0-beta.7",
    "scope": null,
    "escapedName": "angularfire2",
    "name": "angularfire2",
    "rawSpec": "^2.0.0-beta.7",
    "spec": ">=2.0.0-beta.7 <3.0.0",
    "type": "range"
  },
  "_requiredBy": [
    "/"
  ],
  "_resolved": "https://registry.npmjs.org/angularfire2/-/angularfire2-2.0.0-beta.7.tgz",
  "_shasum": "ce4f98467c5a8b2cc1dfd607fda718aee8d64521",
  "_shrinkwrap": null,
  "_spec": "angularfire2@^2.0.0-beta.7",
  "_where": "/Users/Scott/Desktop/test-application-master 2",
  "author": {
    "name": "jeffbcross,davideast"
  },
  "bugs": {
    "url": "https://github.com/angular/angularfire2/issues"
  },
  "dependencies": {},
  "description": "<p align=\"center\">   <h1 align=\"center\">AngularFire2</h1>   <p align=\"center\">The official library for Firebase and Angular 2</p> </p>",
  "devDependencies": {
    "@angular/compiler-cli": "^2.0.0",
    "@angular/platform-server": "^2.0.0-rc.5",
    "@types/jasmine": "^2.5.36",
    "@types/request": "0.0.30",
    "concurrently": "^2.2.0",
    "conventional-changelog-cli": "^1.2.0",
    "es6-module-loader": "^0.17.10",
    "es6-shim": "^0.35.0",
    "gulp": "^3.9.0",
    "gulp-jasmine": "^2.2.1",
    "gulp-typescript": "^2.10.0",
    "http-server": "^0.8.5",
    "jasmine": "^2.4.1",
    "jasmine-core": "^2.4.1",
    "json": "^9.0.3",
    "karma": "^0.13.19",
    "karma-chrome-launcher": "^0.2.2",
    "karma-firefox-launcher": "^0.1.7",
    "karma-jasmine": "^0.3.6",
    "karma-mocha-reporter": "^2.0.2",
    "karma-systemjs": "^0.10.0",
    "ncp": "^2.0.0",
    "parse5": "^1.3.2",
    "protractor": "3.0.0",
    "reflect-metadata": "0.1.2",
    "rimraf": "^2.5.4",
    "rollup": "^0.35.11",
    "rollup-watch": "^2.5.0",
    "systemjs": "^0.19.16",
    "systemjs-builder": "^0.15.7",
    "traceur": "0.0.96",
    "typedoc": "github:jeffbcross/typedoc",
    "typescript": "^2.0.2",
    "zone.js": "^0.7.2"
  },
  "directories": {},
  "dist": {
    "shasum": "ce4f98467c5a8b2cc1dfd607fda718aee8d64521",
    "tarball": "https://registry.npmjs.org/angularfire2/-/angularfire2-2.0.0-beta.7.tgz"
  },
  "homepage": "https://github.com/angular/angularfire2#readme",
  "keywords": [
    "angular2",
    "angular",
    "firebase"
  ],
  "license": "MIT",
  "main": "bundles/angularfire2.umd.js",
  "maintainers": [
    {
      "name": "angularcore",
      "email": "angular-core+npm@google.com"
    },
    {
      "name": "davideast",
      "email": "dceast@gmail.com"
    },
    {
      "name": "jeffbcross",
      "email": "middlefloor@gmail.com"
    }
  ],
  "module": "index.js",
  "name": "angularfire2",
  "optionalDependencies": {},
  "peerDependencies": {
    "@angular/common": "^2.0.0",
    "@angular/compiler": "^2.0.0",
    "@angular/core": "^2.0.0",
    "@angular/platform-browser": "^2.0.0",
    "@angular/platform-browser-dynamic": "^2.0.0",
    "firebase": "^3.0.0",
    "rxjs": "^5.0.1"
  },
  "readme": "ERROR: No README data found!",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/angular/angularfire2.git"
  },
  "scripts": {},
  "typings": "index.d.ts",
  "version": "2.0.0-beta.7"
}
Run Code Online (Sandbox Code Playgroud)

mxi*_*xii 2

你应该创建一个LoginService

并单独登录和验证订阅。

export class LoginService {

   public isLoggedIn = false;
   private _authSubsription;

   constructor(private _af: AngularFire) {
      this._authSubscription = this._af.auth.subscribe(auth => {
         if (!auth) {
            console.log('LOGGED OUT!!');
            this.isLoggedIn = false;
            return;
         }

         this.isLoggedIn = true;

         // do your stuff here ..
      });
   }

   public login() {
      this._af.auth.login({
         provider: AuthProviders.Facebook,
         method: AuthMethods.Popup,
         scope: ['public_profile']
      });
   }

   public logout() {
      this._af.auth.logout();
   }
}
Run Code Online (Sandbox Code Playgroud)

查看我的分支: https: //github.com/mxii/test-application

和公关: https: //github.com/Atkinson88/test-application/pull/1

您的LoginService. 它实例化了两次,我不知道为什么。