I have created a new Angular 8 CLI project with integration to FirebaseUI Auth, using email and password login. The FirebaseUI Auth widget will not show after user logout. Is this a bug or am I missing something from the documentation?
The app is a Single Page Application.
I have registered Firebase according to documentation in app.module.ts:
// 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);
In a frontpage.component.html I have implemented the FirebaseUI widget according to documentation:
<h1>Welcome - User is logged out!</h1>
<div id="firebaseui-auth-container"></div>
<div id="loader">Loading...</div>
In frontpage.component.ts i have:
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();
}
}
user-profile.component.html:
<h1>Welcome - User is logged in!</h1>
<button mat-raised-button color="primary" (click)="signOut()">Sign out</button>
user-profile.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 is injected in app.component.ts, where firebase.auth().onAuthStateChanged is called on changes in the Auth object -resulting i routing:
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']);
}
});
}
}