Angular Firebase+;ngrx+;身份验证的多个提供程序
Firebase有一个奇怪的场景,当有人首先向google提供商登录时,您将无法向您在本问题中看到的其他提供商登录 最后,我按照上述问题的2个第一个答案实现了这一点,但有1个问题和1个改进 问题是,为什么当我使用异步内部catchError时,它期望正常的操作而不是可观察的操作 改进之处在于,当我调用弹出窗口时,有没有办法隐藏它?或者避免再次调用SigninProvider操作?(原因是用户将看到2个弹出窗口) 全面效果Angular Firebase+;ngrx+;身份验证的多个提供程序,angular,firebase,firebase-authentication,ngrx,Angular,Firebase,Firebase Authentication,Ngrx,Firebase有一个奇怪的场景,当有人首先向google提供商登录时,您将无法向您在本问题中看到的其他提供商登录 最后,我按照上述问题的2个第一个答案实现了这一点,但有1个问题和1个改进 问题是,为什么当我使用异步内部catchError时,它期望正常的操作而不是可观察的操作 改进之处在于,当我调用弹出窗口时,有没有办法隐藏它?或者避免再次调用SigninProvider操作?(原因是用户将看到2个弹出窗口) 全面效果 @Effect() signInProvider: Observa
@Effect()
signInProvider: Observable<Action> = this.actions$.pipe(
ofType(AuthActionTypes.SIGNIN_PROVIDER),
map((action: SigninProvider) => action.payload),
switchMap((provider) => {
let result: any;
let provi = provider;
if (provider === 'google') {
result = this.firebaseAuthService.signInGoogleLogin();
} else if (provider === 'facebook') {
result = this.firebaseAuthService.signInFacebookLogin();
} else if (provider === 'twitter') {
result = this.firebaseAuthService.signInTwitterLogin();
}
const resultAction: Observable<Action> = result.pipe(
switchMap((userSignIn) => {
console.log("TCL: AuthEffects -> userSignIn", userSignIn)
return combineLatest(this.afAuth.authState.pipe(take(1)), of(userSignIn));
}),
switchMap(([user, userFromProvider]) => {
console.log("TCL: AuthEffects -> user", user)
const userEmail = user.email ? user.email : userFromProvider.additionalUserInfo.profile.email;
const userDto: CreateUserProviderDto = {
uid: user.uid,
fullName: user.displayName,
username: userEmail,
email: userEmail,
terms: true
};
return combineLatest(of(user), from(user.getIdToken()), this.usersService.usersSignInProviderPost(userDto));
}),
map(([user, token, userFromBackend]) => {
const currentUser: CurrentUser = {
token: token, refreshToken: user.refreshToken, user: {
_id: userFromBackend._id,
uid: userFromBackend.uid,
email: userFromBackend.email,
profile: userFromBackend.profile,
fullName: userFromBackend.fullName,
username: userFromBackend.username
}
};
this.localStorageService
.setItem(AUTH_KEY, {
token: token,
refreshToken: user.refreshToken,
isAuthenticated: true,
user: currentUser.user
});
this.ngZone.run(() => {
this.router.navigate(['/']);
});
return new SigninProviderSuccess(currentUser);
}),
catchError(async (error) => {
let displayMessage;
if (error.email && error.credential && error.code === 'auth/account-exists-with-different-credential') {
const providers = await this.afAuth.auth.fetchSignInMethodsForEmail(error.email)
const firstPopupProviderMethod =
providers.find(p => this.firebaseAuthService.supportedPopupSignInMethods.includes(p));
// Test: Could this happen with email link then trying social provider?
if (!firstPopupProviderMethod) {
throw new Error(`Your account is linked to a provider that isn't supported.`);
}
const linkedProvider = this.firebaseAuthService.getProvider(firstPopupProviderMethod);
linkedProvider.setCustomParameters({ login_hint: error.email });
const resultProvider = await this.afAuth.auth.signInWithPopup(linkedProvider);
await resultProvider.user.linkWithCredential(error.credential);
return new SigninProvider(provi);
} else if (typeof error === 'object'
&& error !== null
&& error.hasOwnProperty('code')
&& error.hasOwnProperty('message')) {
const errorNoTypes: any = { ...error };
displayMessage = `${errorNoTypes.code} - ${error.message}`;
this.toastrService.danger('Try it again!', displayMessage, {
duration: 8000
});
}
return new RetrieveError(error);
}),
);
return resultAction;
})
);
@Effect()
signInProvider:Observable=此.actions$.pipe(
ofType(AuthActionTypes.SIGNIN_PROVIDER),
映射((操作:SigninProvider)=>操作有效负载),
开关映射((提供程序)=>{
让结果:任何;
设provi=provider;
如果(提供程序=='google'){
结果=this.firebaseAuthService.SigningLogleLogin();
}else if(提供程序=='facebook'){
结果=this.firebaseAuthService.signInFacebookLogin();
}else if(提供程序==='twitter'){
结果=this.firebaseAuthService.signInTwitterLogin();
}
const resultAction:Observable=result.pipe(
开关映射((用户登录)=>{
log(“TCL:AuthEffects->userSignIn”,userSignIn)
返回combineLatest(this.afAuth.authState.pipe(take(1)),of(userSignIn));
}),
switchMap(([user,userFromProvider])=>{
log(“TCL:authfacts->user”,user)
const userEmail=user.email?user.email:userFromProvider.additionalUserInfo.profile.email;
const userDto:CreateUserProviderDto={
uid:user.uid,
全名:user.displayName,
用户名:userEmail,
电子邮件:userEmail,
术语:正确
};
返回combineTest(of(user),from(user.getIdToken()),this.usersService.usersSignInProviderPost(userDto));
}),
映射([user,token,userFromBackend])=>{
常数currentUser:currentUser={
令牌:令牌,刷新令牌:用户。刷新令牌,用户:{
_id:userFromBackend.\u id,
uid:userFromBackend.uid,
电子邮件:userFromBackend.email,
配置文件:userFromBackend.profile,
全名:userFromBackend.fullName,
用户名:userFromBackend.username
}
};
这是localStorageService
.setItem(身份验证密钥{
令牌:令牌,
refreshToken:user.refreshToken,
我证实:是的,
用户:currentUser.user
});
此.ngZone.run(()=>{
this.router.navigate(['/']);
});
返回新的SigninProviderSuccess(当前用户);
}),
catchError(异步(错误)=>{
让我们显示消息;
if(error.email&&error.credential&&error.code===='auth/account以不同的凭据存在'){
const providers=wait this.afAuth.auth.fetchSigningMethodForemail(error.email)
常数firstPopupProviderMethod=
providers.find(p=>this.firebaseAuthService.supportedPopupSigningMethods.includes(p));
//测试:这会发生在电子邮件链接,然后尝试社交提供商?
如果(!firstPopupProviderMethod){
抛出新错误(`您的帐户链接到不受支持的提供商。`);
}
const linkedProvider=this.firebaseAuthService.getProvider(firstPopupProviderMethod);
setCustomParameters({login\u hint:error.email});
const resultProvider=wait this.afAuth.auth.signInWithPopup(linkedProvider);
等待resultProvider.user.linkWithCredential(错误.credential);
返回新的签名提供者(provi);
}else if(错误类型==='object'
&&错误!==null
&&错误。hasOwnProperty('code'))
&&错误。hasOwnProperty('message')){
const errorNoTypes:any={…error};
displayMessage=`${errorNoTypes.code}-${error.message}`;
this.toastrService.danger('再试一次!'),displayMessage{
持续时间:8000
});
}
返回新的RetrieveError(错误);
}),
);
返回结果;
})
);
@Effect()
signInProvider: Observable<Action> = this.actions$.pipe(
ofType(AuthActionTypes.SIGNIN_PROVIDER),
map((action: SigninProvider) => action.payload),
switchMap((provider) => {
let result: any;
let provi = provider;
if (provider === 'google') {
result = this.firebaseAuthService.signInGoogleLogin();
} else if (provider === 'facebook') {
result = this.firebaseAuthService.signInFacebookLogin();
} else if (provider === 'twitter') {
result = this.firebaseAuthService.signInTwitterLogin();
}
const resultAction: Observable<Action> = result.pipe(
switchMap((userSignIn) => {
console.log("TCL: AuthEffects -> userSignIn", userSignIn)
return combineLatest(this.afAuth.authState.pipe(take(1)), of(userSignIn));
}),
switchMap(([user, userFromProvider]) => {
console.log("TCL: AuthEffects -> user", user)
const userEmail = user.email ? user.email : userFromProvider.additionalUserInfo.profile.email;
const userDto: CreateUserProviderDto = {
uid: user.uid,
fullName: user.displayName,
username: userEmail,
email: userEmail,
terms: true
};
return combineLatest(of(user), from(user.getIdToken()), this.usersService.usersSignInProviderPost(userDto));
}),
map(([user, token, userFromBackend]) => {
const currentUser: CurrentUser = {
token: token, refreshToken: user.refreshToken, user: {
_id: userFromBackend._id,
uid: userFromBackend.uid,
email: userFromBackend.email,
profile: userFromBackend.profile,
fullName: userFromBackend.fullName,
username: userFromBackend.username
}
};
this.localStorageService
.setItem(AUTH_KEY, {
token: token,
refreshToken: user.refreshToken,
isAuthenticated: true,
user: currentUser.user
});
this.ngZone.run(() => {
this.router.navigate(['/']);
});
return new SigninProviderSuccess(currentUser);
}),
catchError(async (error) => {
let displayMessage;
if (error.email && error.credential && error.code === 'auth/account-exists-with-different-credential') {
const providers = await this.afAuth.auth.fetchSignInMethodsForEmail(error.email)
const firstPopupProviderMethod =
providers.find(p => this.firebaseAuthService.supportedPopupSignInMethods.includes(p));
// Test: Could this happen with email link then trying social provider?
if (!firstPopupProviderMethod) {
throw new Error(`Your account is linked to a provider that isn't supported.`);
}
const linkedProvider = this.firebaseAuthService.getProvider(firstPopupProviderMethod);
linkedProvider.setCustomParameters({ login_hint: error.email });
const resultProvider = await this.afAuth.auth.signInWithPopup(linkedProvider);
await resultProvider.user.linkWithCredential(error.credential);
return new SigninProvider(provi);
} else if (typeof error === 'object'
&& error !== null
&& error.hasOwnProperty('code')
&& error.hasOwnProperty('message')) {
const errorNoTypes: any = { ...error };
displayMessage = `${errorNoTypes.code} - ${error.message}`;
this.toastrService.danger('Try it again!', displayMessage, {
duration: 8000
});
}
return new RetrieveError(error);
}),
);
return resultAction;
})
);