Home > Blockchain >  React Firebase is not returning error message even after giving wrong input
React Firebase is not returning error message even after giving wrong input

Time:05-16

I am using React Firebase hook to log in to my website. when trying to log in with the wrong email or password in the login form, an error message will be returned from the React firebase hook. But even after giving the wrong input, an error message is not returning

const Login = () => {
  const [signInWithEmailAndPassword, error] =
    useSignInWithEmailAndPassword(auth);
    
  const location = useLocation();
  const navigate = useNavigate();

  const from = location?.state?.from?.pathname || '/';
  
  
   if (error) {
     return (
       <div>
         <p>Error: {error.message}</p>
       </div>
     );
   }
    const handleLogIn = (e) => {
      e.preventDefault();
      const email = e.target.email.value;
      const password = e.target.password.value;
      signInWithEmailAndPassword(email, password)
      e.target.reset();
      navigate(from, { replace: true })
      
    }

CodePudding user response:

You are using signInWithEmailAndPassword hook incorrectly. signInWithEmailAndPassword returns an array & 3th index is of error message.

You can follow this: https://github.com/CSFrequency/react-firebase-hooks/blob/master/auth/README.md#usesigninwithemailandpassword

const [
  signInWithEmailAndPassword,
  user,
  loading,
  error,
] = useSignInWithEmailAndPassword(auth);

Since, useSignInWithEmailAndPassword returns an Array, We need to extract/destructure the value from respective index.

Apart from that, You must also use loading to display whether firebase is still authorizing the request or not (Loading State).

CodePudding user response:

The signInWithEmailAndPassword appears to be an async function and your code isn't waiting for the returned Promise to resolve. I'm guessing you are seeing the navigate("/"); called and the app is navigating to the home page.

const handleLogIn = (e) => {
  e.preventDefault();
  const email = e.target.email.value;
  const password = e.target.password.value;
  signInWithEmailAndPassword(email, password); // <-- no waiting for promise
  e.target.reset();
  navigate(from, { replace: true }); // <-- navigate away
};

useSignInWithEmailAndPassword

export default (auth: Auth): EmailAndPasswordActionHook => {
  const [error, setError] = useState<AuthError>();
  const [loggedInUser, setLoggedInUser] = useState<UserCredential>();
  const [loading, setLoading] = useState<boolean>(false);

  const signInWithEmailAndPassword = async (
    email: string,
    password: string
  ) => {
    setLoading(true);
    setError(undefined);
    try {
      const user = await firebaseSignInWithEmailAndPassword(
        auth,
        email,
        password
      );
      setLoggedInUser(user);
    } catch (err) {
      setError(err as AuthError);
    } finally {
      setLoading(false);
    }
  };

  const resArray: EmailAndPasswordActionHook = [
    signInWithEmailAndPassword,
    loggedInUser,
    loading,
    error,
  ];
  return useMemo<EmailAndPasswordActionHook>(() => resArray, resArray);
};

The handleLogin handler should probably wait for the Promise to settle so any errors can be returned by the hook. It turns out though that signInWithEmailAndPassword also doesn't return any resolve/rejected values, so there's no way to know the authentication was successful from within the handleLogIn callback function, the component will need to use the hook's returned loading and loggedInUser states to determine if it is safe to navigate.

Example:

const Login = () => {
  const [
    signInWithEmailAndPassword,
    loggedInUser,
    loading,
    error,
  ] = useSignInWithEmailAndPassword(auth);
    
  const location = useLocation();
  const navigate = useNavigate();

  const from = location?.state?.from?.pathname || '/';

  useEffect(() => {
    if (!loading && loggedInUser) {
      navigate(from, { replace: true });
  }, [loggedInUser, loading, navigate, from]);
    
  if (error) {
    return (
      <div>
        <p>Error: {error.message}</p>
      </div>
    );
  }

  const handleLogIn = (e) => {
    e.preventDefault();
    const email = e.target.email.value;
    const password = e.target.password.value;
    signInWithEmailAndPassword(email, password)
    e.target.reset();
  }

  ...
  • Related