Reputation: 122
I'm new to Firebase, and I'm trying to implement authentication from an angular 7 application.
Here is my Authentication service:
@Injectable({
providedIn: 'root'
})
export class AuthService {
private user: Observable<firebase.User>;
private userDetails: firebase.User;
constructor(private angularFireAuth: AngularFireAuth) {
this.user = this.angularFireAuth.user;
this.user.subscribe(
(user) => {
if (user) {
this.userDetails = user;
}
else {
this.userDetails = null;
}
}
);
}
signInGoogleLogin() {
return this.angularFireAuth.auth.setPersistence(firebase.auth.Auth.Persistence.LOCAL)
.then(() =>
this.angularFireAuth.auth.signInWithPopup(
new firebase.auth.GoogleAuthProvider()
)
);
}
isLoggedIn(): boolean {
return this.userDetails != null;
}
}
And here is my AuthGuard implementation:
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router, private authService: AuthService) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<boolean> | Promise<boolean> | boolean {
if (this.authService.isLoggedIn()) {
return true;
}
this.router.navigate(['login'], { queryParams: { returnUrl: state.url}});
return false;
}
}
My problem is: the persistence does not seem to work. Whenever I refresh the page, I have to log in, whenever I'm navigating to another component that needs authentication, I need to log in again.
Of course, if I use "signInWithRedirect" instead of "signInWithPopup" I fall into a logging loop where I get redirected to my login page which finds that I'm not logged in, then try to log me, redirects me to my login page which finds I'm not logged in, and so on.
I think all these problems are actually related to the same problem: my auth state persistence implementation is somewhat wrong.
So my question is really simple: what am I doing wrong ? :)
I'd like to be able to log in, and then stay logged in when a refresh occurs.
Thank you for your help. :)
Upvotes: 4
Views: 4512
Reputation: 2420
If anyone comes here looking for an answer this is how I did it
auth.service.ts
import { auth, firestore } from 'firebase/app';
constructor(
private _fAuth: AngularFireAuth,
) {}
public async login(authInfo: UserAuthInfo) {
if(authInfo.rememberMe) {
await this._fAuth.setPersistence(auth.Auth.Persistence.LOCAL)
console.log("local persistance", true);
}
const credential = await this._fAuth.signInWithEmailAndPassword(authInfo.username, authInfo.pass);
...
}
auth.guard.ts
export class AuthGuard implements CanActivate {
constructor(
private _fAuth: AngularFireAuth,
private _router: Router
) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> {
return this._authService.fAuth.authState.pipe(
first(),
map(user => !!user),
tap(authenticated => {
console.log("auth guard loggedin", authenticated);
authenticated || this._router.parseUrl('/auth/login')
})
)
}
}
Upvotes: 3