我有一个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。我无法弄清楚为什么会发生这种情况或如何解决这个问题。我确定我错过了一些东西,但我无法弄清楚是什么。
答案 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);
});
}
}