angular - 在 Angular 8 单页应用程序中重新渲染 FirebaseUI Auth 小部件不起作用
问题描述
我使用电子邮件和密码登录创建了一个新的 Angular 8 CLI 项目,该项目与 FirebaseUI Auth 集成。FirebaseUI Auth 小部件在用户注销后不会显示。这是一个错误还是我从文档中遗漏了什么?
该应用程序是一个单页应用程序。
我已经根据app.module.ts中的文档注册了 Firebase :
// Firebase App (the core Firebase SDK) is always required and must be listed first
import * as firebase from "firebase/app";
// If you enabled Analytics in your project, add the Firebase SDK for Analytics
import "firebase/analytics";
// Add the Firebase products that you want to use
import "firebase/auth";
import "firebase/firestore";
// Initialize Firebase
firebase.initializeApp(environment.firebaseConfig);
在frontpage.component.html中,我根据文档实现了 FirebaseUI 小部件:
<h1>Welcome - User is logged out!</h1>
<div id="firebaseui-auth-container"></div>
<div id="loader">Loading...</div>
在frontpage.component.ts我有:
import { Component, OnInit } from '@angular/core';
import * as firebase from 'firebase/app';
import * as firebaseui from 'firebaseui';
import { Router } from '@angular/router';
@Component({
selector: 'app-frontpage',
templateUrl: './frontpage.component.html',
styleUrls: ['./frontpage.component.less']
})
export class FrontpageComponent implements OnInit {
ui: firebaseui.auth.AuthUI
constructor(private router: Router) {
}
ngOnInit() {
if(firebaseui.auth.AuthUI.getInstance("[DEFAULT]") === null){
// Initialize the FirebaseUI Widget using Firebase.
this.ui = new firebaseui.auth.AuthUI(firebase.auth());
}else{
this.ui = firebaseui.auth.AuthUI.getInstance("[DEFAULT]");
}
var firebaseUIConfig = {
callbacks: {
signInSuccessWithAuthResult: function (authResult, redirectUrl) {
// User successfully signed in.
// Return type determines whether we continue the redirect automatically
// or whether we leave that to developer to handle.
//Manual override to let firebase.auth().onAuthStateChanged handle routing (instead of signInSuccessUrl shown below)
return false;
//return true;
},
uiShown: function () {
// The widget is rendered.
// Hide the loader.
document.getElementById('loader').style.display = 'none';
}
},
// Will use popup for IDP Providers sign-in flow instead of the default, redirect.
signInFlow: 'popup',
signInSuccessUrl: '<url-to-redirect-to-on-success>',
signInOptions: [
// Leave the lines as is for the providers you want to offer your users.
//firebase.auth.GoogleAuthProvider.PROVIDER_ID,
//firebase.auth.FacebookAuthProvider.PROVIDER_ID,
//firebase.auth.TwitterAuthProvider.PROVIDER_ID,
//firebase.auth.GithubAuthProvider.PROVIDER_ID,
//firebase.auth.EmailAuthProvider.PROVIDER_ID,
{
provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
requireDisplayName: false
}
//firebase.auth.PhoneAuthProvider.PROVIDER_ID
],
// Terms of service url.
tosUrl: '<your-tos-url>',
// Privacy policy url.
privacyPolicyUrl: '<your-privacy-policy-url>'
};
this.ui.reset(); // according to https://github.com/firebase/firebaseui-web#tips-for-initializing-a-new-ui-instance-with-the-same-auth-instance
// The start method will wait until the DOM is loaded.
this.ui.start('#firebaseui-container', firebaseUIConfig);
}
ngOnDestroy() {
// according to https://github.com/firebase/firebaseui-web#050
this.ui.reset(); // according to https://github.com/firebase/firebaseui-web#tips-for-initializing-a-new-ui-instance-with-the-same-auth-instance
this.ui.delete();
}
}
用户配置文件.component.html:
<h1>Welcome - User is logged in!</h1>
<button mat-raised-button color="primary" (click)="signOut()">Sign out</button>
用户配置文件.component.ts:
import { Component, OnInit } from '@angular/core';
import * as firebase from 'firebase/app';
@Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.less']
})
export class UserProfileComponent implements OnInit {
constructor() { }
ngOnInit() {
}
signOut(){
firebase.auth().signOut();
}
}
authentication.service.ts被注入app.component.ts,其中firebase.auth ().onAuthStateChanged在 Auth 对象的变化上被调用 - 导致我路由:
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import * as firebase from 'firebase/app';
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
isLoggedIn = false;
constructor(private router: Router) {
firebase.auth().onAuthStateChanged(user => {
if (user) {
// User is signed in.
this.isLoggedIn = true;
this.router.navigate(['/profile']);
} else {
// No user is signed in.
this.isLoggedIn = false;
this.router.navigate(['/frontpage']);
}
});
}
}
解决方案
您应该考虑使用AngularFire。Firebase
这是集成到您的 Angular 应用程序中的最佳选择。
FirebaseUI-web是可选的,您可以将它与 AngularFire 一起使用,例如用于 UI 登录按钮。
安装和使用 AngularFire
yarn add @angular/fire
.
导入AngularFireModule
并AngularFireAuthModule
在您的应用程序模块中:
const config = {
apiKey: "YOUR API KEY",
authDomain: "PROJECT_ID.firebaseapp.com",
};
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AngularFireModule.initializeApp(config),
AngularFireAuthModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
然后,在组件中使用它(来自官方文档的代码片段):
import { Component } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { auth } from 'firebase/app';
@Component({
selector: 'app-root',
template: `
<div *ngIf="auth.user | async as user; else showLogin">
<h1>Hello {{ user.displayName }}!</h1>
<button (click)="logout()">Logout</button>
</div>
<ng-template #showLogin>
<p>Please login.</p>
<button (click)="login()">Login with Google</button>
</ng-template>
`,
})
export class AppComponent {
constructor(public auth: AngularFireAuth) {
}
login() {
this.auth.signInWithPopup(new auth.GoogleAuthProvider());
}
logout() {
this.auth.signOut();
}
}
FirebaseUI-Web 作为一个选项
例如,您还可以使用FirebaseUI-Web来集成不同提供商的“登录”按钮,它可以与AngularFire一起正常工作。
为此,请查看:
- 这个问题和答案,关于 FirebaseAuth UI 和 AngularFire。
- FirebaseUI 与 Angular 的包装器项目
推荐阅读
- angular - 限制角树组件中选择的节点数
- python - 如何导航到 BeautifulSoup 对象中的某些标签?
- laravel - Laravel - 不正确的表定义;只能有一个自动列,并且必须将其定义为键”
- python - 网格倒角(顶点,面)
- go - 有什么方法可以使用自定义查询进行预加载
- laravel - 如何在 Laravel 查询生成器中计算“位置”匹配记录
- reactjs - 需要部署一个与 rasa 模型集成的 React Web 应用程序
- r - Shint:如何显示在 for 循环中更新的文本?
- python-3.x - 时间序列分解:ValueError: You must specify a period or x must be a pandas object with a DatetimeIndex with a freq not set to None
- javascript - 反应中的对象克隆