最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Firebase Authentication not persisting - Stack Overflow

programmeradmin2浏览0评论

Authentication doesn't seem to persist after page has been refreshed. Even after using firebase.auth.Auth.Persistence.LOCAL.

Whenever I log into my app, it successfully redirects me to the Dashboard. But, when page has been refreshed, accessing Dashboard is not possible.

Here's my code.

Filename: loginponent.ts

import { Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';

import * as firebase from 'firebase/app';
import { Observable } from 'rxjs/Observable';
import { AngularFireAuth } from 'angularfire2/auth';
import { AngularFirestore } from 'angularfire2/firestore';

@Component({
    ...
})
export class LoginComponent implements OnInit {

    email: string = '';
    password: string = '';

    constructor(public afAuth: AngularFireAuth, private router: Router, private fb: FormBuilder) {}

    signIn(credentials) {
        this.email = credentials.email;
        this.password = credentials.password;

        this.afAuth.auth.setPersistence(firebase.auth.Auth.Persistence.LOCAL).then(() => {
            this.afAuth.auth.signInWithEmailAndPassword(this.email, this.password).then(() => {
                this.router.navigate(['dashboard']);
            }).catch((err) => {
                ...
            })
        }).catch((err) => {
            ...
        })
    }

    ngOnInit() {}

}

Filename: auth.guard.ts

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';

import { AngularFireAuth } from 'angularfire2/auth';

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(private router: Router, private afAuth: AngularFireAuth) {}

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        var authed = this.afAuth.auth.currentUser;

        if (authed) {
            return true;
        } else {
            this.router.navigate(['/']);
            return false;
        }
    }
}

Additional Info:

@angular/animations: 5.0.0
@angular/common: 5.0.0
@angular/compiler: 5.0.0
@angular/core: 5.0.0
@angular/forms: 5.0.0
@angular/http: 5.0.0
@angular/platform-browser: 5.0.0
@angular/platform-browser-dynamic: 5.0.0
@angular/router: 5.0.0
angular2-materialize: 15.1.10
angularfire2: 5.0.0-rc.3
core-js: 2.4.1
firebase: 4.6.1
hammerjs: 2.0.8
jquery: 2.2.4
materialize-css: 0.100.2
rxjs: 5.5.2
zone.js: 0.8.14

Expected Result:

http://localhost:4200/dashboard (ACCESSIBLE WHILE LOGGED IN)

Current Result:

http://localhost:4200/dashboard (INACCESSIBLE WHILE LOGGED IN; REDIRECTS TO HOME)

Where did I go wrong or something else?

Authentication doesn't seem to persist after page has been refreshed. Even after using firebase.auth.Auth.Persistence.LOCAL.

Whenever I log into my app, it successfully redirects me to the Dashboard. But, when page has been refreshed, accessing Dashboard is not possible.

Here's my code.

Filename: login.component.ts

import { Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';

import * as firebase from 'firebase/app';
import { Observable } from 'rxjs/Observable';
import { AngularFireAuth } from 'angularfire2/auth';
import { AngularFirestore } from 'angularfire2/firestore';

@Component({
    ...
})
export class LoginComponent implements OnInit {

    email: string = '';
    password: string = '';

    constructor(public afAuth: AngularFireAuth, private router: Router, private fb: FormBuilder) {}

    signIn(credentials) {
        this.email = credentials.email;
        this.password = credentials.password;

        this.afAuth.auth.setPersistence(firebase.auth.Auth.Persistence.LOCAL).then(() => {
            this.afAuth.auth.signInWithEmailAndPassword(this.email, this.password).then(() => {
                this.router.navigate(['dashboard']);
            }).catch((err) => {
                ...
            })
        }).catch((err) => {
            ...
        })
    }

    ngOnInit() {}

}

Filename: auth.guard.ts

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';

import { AngularFireAuth } from 'angularfire2/auth';

@Injectable()
export class AuthGuard implements CanActivate {

    constructor(private router: Router, private afAuth: AngularFireAuth) {}

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        var authed = this.afAuth.auth.currentUser;

        if (authed) {
            return true;
        } else {
            this.router.navigate(['/']);
            return false;
        }
    }
}

Additional Info:

@angular/animations: 5.0.0
@angular/common: 5.0.0
@angular/compiler: 5.0.0
@angular/core: 5.0.0
@angular/forms: 5.0.0
@angular/http: 5.0.0
@angular/platform-browser: 5.0.0
@angular/platform-browser-dynamic: 5.0.0
@angular/router: 5.0.0
angular2-materialize: 15.1.10
angularfire2: 5.0.0-rc.3
core-js: 2.4.1
firebase: 4.6.1
hammerjs: 2.0.8
jquery: 2.2.4
materialize-css: 0.100.2
rxjs: 5.5.2
zone.js: 0.8.14

Expected Result:

http://localhost:4200/dashboard (ACCESSIBLE WHILE LOGGED IN)

Current Result:

http://localhost:4200/dashboard (INACCESSIBLE WHILE LOGGED IN; REDIRECTS TO HOME)

Where did I go wrong or something else?

Share Improve this question edited Nov 6, 2017 at 15:07 Frank van Puffelen 599k84 gold badges888 silver badges858 bronze badges asked Nov 6, 2017 at 10:36 EtosticityEtosticity 2374 silver badges14 bronze badges 5
  • 1 Are you using onAuthStateChanged listener to properly detect the current user state? – bojeil Commented Nov 7, 2017 at 9:24
  • @bojeil As shown in auth.guard.ts, I'm not using onAuthStateChanged to listen for Authentication Changes. Is that the problem or something else? – Etosticity Commented Nov 7, 2017 at 15:30
  • 1 Yes that is the issue. That is the proper way to detect the initial Auth state. – bojeil Commented Nov 7, 2017 at 19:15
  • @bojeil Please make it an answer for me to mark this question as completed. – Etosticity Commented Nov 8, 2017 at 12:14
  • I have added my comment as an answer. – bojeil Commented Nov 9, 2017 at 8:04
Add a comment  | 

2 Answers 2

Reset to default 24

You need to use onAuthStateChanged listener to detect the initial auth state:

firebase.auth().onAuthStateChanged(user => {
  if (user) {
    // User is signed in.
  } else {
    // User is signed out.
  }
});

TL;DR:

For people who come here using expo sdk >=48 or after updating React Native to >=0.71, you need to initialize firebaseAuth with a custom storage like so:

import { initializeAuth } from 'firebase/auth';
import { getApp } from 'firebase/app';
import { getReactNativePersistence } from 'firebase/auth/react-native';
import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage';

const storage = getReactNativePersistence(ReactNativeAsyncStorage)
const app = getApp();

initializeAuth(app, {
  persistence: storage,
});

Explanation:

AsyncStorage got removed from React Native in V 0.71 as it was deprecated for a long time now. Unfortunately firebase auth is still relying on the integrated AsyncStorage under the hood.

The result is that (even when using onAuthStateChanged as explained in other answers) getAuth().currentUser will always be null after closing the app and opening it again.

The issue is explained in more detail here: https://github.com/firebase/firebase-js-sdk/pull/7128

发布评论

评论列表(0)

  1. 暂无评论