【问题标题】:AngularFire Auth Persistence cannot be invoked without 'new'没有'new'就不能调用AngularFire Auth Persistence
【发布时间】:2022-01-07 23:21:22
【问题描述】:

我正在尝试使用以下代码在 angularfire 中通过持久性来实现身份验证:

constructor(private auth: Auth, private router: Router) {
    if (auth.currentUser) this.router.navigate(this.redirect);
  }

  async loginWithGoogle() {
    const provider = new GoogleAuthProvider();

    try {
      await setPersistence(this.auth, browserLocalPersistence);
      await signInWithPopup(this.auth, provider);
      this.message = 'Sign in successful';
      await this.router.navigate(this.redirect);
    } catch (error: any) {
      console.error(error);
      if (error.code) {
        this.message = `${error.code}: ${error.message}`;
      } else {
        this.message = 'There was a problem signing in. Please try again.';
      }
    }
  }

但是,无论setPersistence 方法的位置如何,我总是会收到此错误:

Class constructor BrowserLocalPersistence cannot be invoked without 'new'

我按照文档 (https://firebase.google.com/docs/auth/web/auth-state-persistence) 到了 T;我做错了什么?

我正在使用 Angular 13、Angularfire 7 和 Firebase 9。

【问题讨论】:

  • 如果您知道您有特定的用例需要,我强烈建议您只致电setPersistence。在大多数浏览器上,Firebase 已经在重新加载之间保持身份验证状态,而无需调用 setPersistence
  • 我没有看到...我想我什至不需要设置持久性;谢谢!

标签: angular firebase firebase-authentication angularfire2 rxfire


【解决方案1】:

来自persisting auth state persistence in the JavaScript/web SDK上的文档:

对于 Web 应用程序,默认行为是即使在用户关闭浏览器后仍保留用户的会话。

如果您知道自己有特定的用例需要,我强烈建议您只致电setPersistence。在大多数浏览器上,Firebase 已经在重新加载之间保持身份验证状态,而无需调用 setPersistence

【讨论】:

  • 只需调用signInWithEmailAndPassword(auth, email, password);不会在重新加载之间保持登录。
  • 如前所述:在大多数浏览器上,Firebase 已经在重新加载之间保持身份验证状态。我刚刚通过指向文档的链接澄清了我的答案。如果这对您不起作用,请打开一个新问题,并尽量减少该问题的重现。
【解决方案2】:

我已将我的登录实现留给下面的提供者。

虽然我还没有在这个项目中迁移到 Modular Firebase V9,但身份验证持久性仍然有效——登录过一次的用户无需每次回来都重新登录。

我发现将身份验证逻辑保留在可以注入到您的组件或模块中的服务中是一种很好的做法。

在构造函数中,您可以找到一种很好的方法来确定您的用户是否已登录并在 Cloud Firestore 中拥有与其身份验证 ID 相关联的个人资料。


export class AuthService {

  analytics = firebase.analytics(); // this declaration works better than constructor init from import
  userCredential; // to store the promise returned when signing up/ in with email & password
  // type: User from the model
  user$: Observable<User>; // defined as observable as it can change when user signs in/out

  constructor(
    // inject imports for fire store auth service in constructor
    private afAuth: AngularFireAuth,
    private afs: AngularFirestore,
    private router: Router
  ) {

    // Get the auth state, then fetch the Firestore user document or return null
    this.user$ = this.afAuth.authState.pipe(  // define the observable state
      switchMap(user => {
        // Logged in
        if (user) { // if user is defined
          // point to document with matching ID
          return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
        } else {
          // Logged out
          return of(null); // allows us to tell when user is not logged in
        }
      })
    );
  }

  /**
   * Authenticate users with Google O-Auth provider
   * @param {boolean=} [registration = false] - whether this is the first sign in or not
   */
  async googleSignIn(registration: boolean = false) {

    // reference google auth provider
    const provider = new auth.GoogleAuthProvider();
    // pass provider to sign in with popup functionality
    this.userCredential = await this.afAuth.signInWithPopup(provider);

    if (registration) { // if the request is coming from the registration page

      try {
        await this.insertNewUser(this.userCredential.user, this.userCredential.user.displayName);
        await this.verifyEmail(); // send a verification email to the user when registering
        await this.router.navigate(['/user-profile']);
      } catch (err) {
        console.log(`Error: ${err.errorMessage}`);
        M.toast({html: `Error: ${err.errorMessage}`, classes: 'rounded materialize-red'});
      }

    } else {  //  user is logging in again

      try {
        await this.router.navigate(['/user-profile']);
        M.toast({html: `Signed in as ${this.userCredential.user.displayName}`, classes: 'rounded blue'});

        // let user know that they haven't been verified
        if (!this.userCredential.emailVerified) {
          console.log(`user's email has not been verified`);
          M.toast({
            html: `Your email has not yet been verified. Please check your inbox.`,
            classes: 'rounded orange darken-2'
          });
        }

      } catch (err) {
        console.log(`Error: ${err.errorMessage}`);
        M.toast({html: `Error: ${err.errorMessage}`, classes: 'rounded materialize-red'});
      }

    }

    // track the login event with analytics
    this.analytics.logEvent('login', {serviceName: 'Google Login'});

  } // end of sign in function

} // end of auth service 

【讨论】:

    猜你喜欢
    • 2021-07-06
    • 2017-09-29
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 2019-04-21
    相关资源
    最近更新 更多