简体   繁体   中英

(Firebase Web Persistence) After sign in, currentUser is null, but, upon inspection of the auth object, it isn't?

I'm trying to access the currently signed in user via getAuth(app).currentUser , but the result I get is super weird, it says the auth.currentUser is null , but, then, upon inspection of the object, it isn't???

在此处输入图像描述

I did try to manually change persistence to see if it changed anything (following the docs ), but it didn't make any difference.

My code (TypeScript) is pretty much this (I'm using the Firebase Emulator):

// Global Variables
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);

...

await signInWithEmailAndPassword(auth, username, password);

For those who wish to see the complete code... Here it is... It's a bit experimental, and, for this project, I'm trying to create the most minimalistic version of this that I can think of. I think the code below with a bit of HTML is pretty much what you need to reproduce it locally.

This is how I'm initializing my Firebase app and auth , which only need to exist in the admin page currently:

import { FirebaseApp, initializeApp } from "firebase/app";
import {
  Auth,
  // browserLocalPersistence,
  connectAuthEmulator,
  getAuth,
} from "firebase/auth";

import { EnvState, envState } from "../infra/env";

export const firebaseConfig = {...};

export let app: FirebaseApp;
export let auth: Auth;

let authInitialized = false;
export const initAuth = async () => {
  try {
    if (!authInitialized) {
      app = initializeApp(firebaseConfig);
      auth = getAuth(app);
      // await auth.setPersistence(browserLocalPersistence);
    
      if (envState === EnvState.dev)
        connectAuthEmulator(auth, "http://localhost:9094", {
          disableWarnings: true,
        });
    }

    authInitialized = true;
  } catch (error) {
    authInitialized = false;
  }
};

And this is the admin view (I'm usign HTML components in this project):

import { onAuthStateChanged, signInWithEmailAndPassword } from "firebase/auth";
import { auth, initAuth } from "../../infra/firebase_config";

export default class AdminView extends HTMLElement {
  static readonly tag: string = "admin-view";
    
  constructor() {
    super();

    // Could be elsewhere, doesn't seem to make a difference (not even with `await`).
    initAuth();
  }

  async connectedCallback() {
    document.title = "Admin";

    // An attempt at trying to get the current user in a different way...
    let currentUser;
    console.log(auth);
    onAuthStateChanged(auth, (user) => {
      if (user) currentUser = user;
    });
    // *********************************************
    // This is the log the picture refers to:
    // *********************************************
    console.log(currentUser);

    if (auth.currentUser) {
      this.innerHTML = `
        <p>You're logged in as ${auth.currentUser}</p>
      `;
    } else {
      this.signInForm();
    }
  }

  signInForm = (): void => {
    this.innerHTML = `
      <form>
        <fieldset>
          <label for="username">Admin</label>
          <input type="text" name="username" autofocus/>
        </fieldset>
      
        <fieldset>
          <label for="password">Password</label>
          <input type="text" name="password"/>
        </fieldset>
        
        <button type="submit">Sign in</button>
      </form>
    `;

    const submitButton: HTMLButtonElement = this.querySelector("button")!;
    submitButton.addEventListener("click", async (e: Event) => {
      e.preventDefault();
      const isLoggedIn = await this.signIn();

      const msg = isLoggedIn
        ? "You're logged in!"
        : "You weren't able to log in...";
      this.innerHTML += `
        <p>${msg}</p>
      `;
    });
  };

  signIn = async (): Promise<boolean> => {
    const adminUserInput: HTMLInputElement = this.querySelector(
      "input[name=username]"
    )!;
    const adminPasswordInput: HTMLInputElement = this.querySelector(
      "input[name=password]"
    )!;

    const username = adminUserInput.value;
    const password = adminPasswordInput.value;

    try {
      const cred = await signInWithEmailAndPassword(auth, username, password);

      if (cred) return true;
      else return false;
    } catch (error) {
      const e = error as Error;
      console.log(e.message);

      return false;
    }
  };
}

The console.log(currentUser); in your code would mostly be null as onAuthStateChanged() may not have loaded the auth state yet. It's best to add that observer when your page loads, perhaps in your constructor like this:

constructor() {
  super();

  // return the auth instance from this function
  const a = initAuth();

  onAuthStateChanged(a, (user) => {
    if (user) {
      console.log(user)
      // save user info in state
    } else {
      console.log("No User, redirect to login")
    }
  });
}

Then you can read your user information from state directly:

// somewhere in state
const userInfo = null;

async connectedCallback() {
  document.title = "Admin";
  if (userInfo) {
    this.innerHTML = `
        <p>You're logged in as ${userInfo}</p>
      `;
  } else {
    this.signInForm();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM