Angular2 AngularFire2 providerData数组未在模板中更新

时间:2016-12-18 16:29:37

标签: angular typescript firebase firebase-authentication angularfire2

我有一个Angular2应用程序,允许使用Firebase(通过AngularFire2)通过Google或Facebook登录。它还允许链接帐户,以便用户可以将他/她的Google和Facebook登录链接到同一个Firebase uid。

在我的ng2用户个人资料组件上,对于当前经过身份验证的用户,我希望能够显示用于关联FB或Google帐户的按钮(如果尚未链接)。 AngularFire2公开了一个FireservAuthState类型的可观察对象,它包含firebase.User类型的“auth”属性。 firebase.User对象包括providerData数组,该数组包含与用户关联的所有提供程序(Facebook,Google,Github等)。我的AuthService看起来像这样:

import * as firebase from 'firebase';
import { Injectable } from '@angular/core';
import { AuthProviders, AuthMethods, 
         FirebaseAuth, FirebaseAuthState } from 'angularfire2';

@Injectable()
export class AuthService {

  authState: FirebaseAuthState = null;

  constructor(private auth$: FirebaseAuth) {
    auth$.subscribe((state) => {this.authState = state;})
  }

  linkTo(provider:string): firebase.Promise<firebase.auth.UserCredential> {
    // provider param is a string (e.g., ‘facebook.com’);
    // linkWithPopup() returns a firebase promise of type firebase.AuthState 
    // Not included here: code to convert provider param from string to 
    // firebase.AuthProvider
    return this.authState.auth.linkWithPopup(provider);
  }

  unLinkFrom(provider:string): firebase.Promise<firebase.auth.UserCredential> {
    // provider is a string (e.g. ‘facebook.com’)
    // unlink() returns a firebase promise of type firebase.User.
    return this.authState.auth.unlink (provider);
  }

我可以使用它来确定哪些提供程序已经与给定用户关联,并隐藏/显示必需的链接按钮,具体取决于提供程序是否包含在用户的providerData数组中。在我的组件中,例如:

export class UserProfileComponent implements OnInit {

  private linkedProviders;

  constructor() {} (private authService: AuthService) {
    this. linkedProviders = authService.authState.auth.providerData;
  }
}

当我链接提供者时,firebase返回一个firebase.Promise对象。在成功链接时,我使用.then()来更新本地linkedProviders数组,该数组包含来自Firebase的providerData数组。例如:

  // Link a provider to the current account
  linkProvider(provider:string) {
    this.authService.linkTo(provider)
      .then((state) => this.linkedProviders = state.user.providerData)
      .catch(err => console.log(err));
  }

  // Unlink a provider from the current account
  unLinkProvider(provider:string) {
    this.authService.unLinkAccount(provider)
      .then(user => this.linkedProviders = user.providerData)
      .catch(err => console.log(err));
  }

然而,当用户链接或取消链接提供者时,使用* ngFor时,this.linkedProviders数组似乎不会在模板中自动更新,尽管linkProvider / unLinkProvider的.then()块将其修改为反映从Firebase Promise返回的更新数据。

实际上,它似乎修改了本地数组数据,因为将this.linkedProviders记录到控制台将显示。但是,除非我单击模板中的其他按钮,否则更改不会应用于* ngFor。我无法弄清楚为什么会发生这种情况或如何解决这个问题。我确定我错过了一些东西,但我无法弄清楚是什么。

1 个答案:

答案 0 :(得分:0)

authState 设置为可观察的更清晰,以便组件可以订阅它。然后,组件可以在订阅中的authState上调用linkWithPopup或unlink。目前看来,在设置authState之前,可以调用linkTo和unlinkFrom方法。

        import * as firebase from 'firebase';
        import { Injectable } from '@angular/core';
        import {
            AuthProviders, AuthMethods,
            FirebaseAuth, FirebaseAuthState
        } from 'angularfire2';
        import { ReplaySubject } from 'rxjs/ReplaySubject';
        import { Observable } from 'rxjs/Observable';

        @Injectable()
        export class AuthService {
            private authStateSource = new ReplaySubject<FirebaseAuthState>(1);
            authState: Observable<FirebaseAuthState> = this.authStateSource.asObservable();

            constructor(private auth$: FirebaseAuth) {
                auth$.subscribe((state) => {
                    this.authStateSource.next(state);
                });
            }
        }