繁体   English   中英

无法从 Firebase 验证电子邮件和密码

[英]Can't verify email and password from Firebase

我正在创建一个注册表单并尝试使电子邮件和密码起作用。 当我使用input并使用适当的值设置状态时,它工作得很好,但是一旦我将 Input 包裹在我的自定义组件周围,它就无法从组件中获取数据到状态中,并给我一个错误,即无法找到用户(即使他们的信息在 Firebase Auth 中)我需要帮助。

身份验证.js

import style from "./auth.module.css";
import { useEffect, useRef, useState } from "react";
import { useAuthState } from 'react-firebase-hooks/auth';
import { auth, signInWithEmailAndPassword, signInWithGoogle } from "../../firebase";
import { CSSTransition } from "react-transition-group";


export default function Auth() {
  const [activeMenu, setActiveMenu] = useState("main");
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [user, loading, error] = useAuthState(auth);

  let domNode = useClickOutside(() => {
    setActiveMenu(false);
  });

  return (
    <div className={style.container}>
      <Login />
      <Signup />
    </div>
  );

  function AuthType(props) {
    return (
      <a
        href={props.link}
        className={style.menuItem}
        onClick={() => props.goToMenu && setActiveMenu(props.goToMenu)}
      >
        {props.children}
      </a>
    );
  }

/* I believe you've switched up the login and sign-up? */
  function Login() {

    return (
      <CSSTransition in={activeMenu === "main"} unmountOnExit timeout={500}>
        <div ref={domNode}>
          <div className={style.login}>
            <h1 className={style.title}>Clip It</h1>
            {/* Email and Password */}
            <Emailform 
              label="Email" 
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              />

            <Passform 
              label="Password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              />

            <div className={style.button}>
              <input 
                type="submit" 
                value="Login"
                onClick={() => signInWithEmailAndPassword(email, password)} />
              <input 
                type="submit" 
                value="Login with Google"
                onClick={signInWithGoogle} />
            </div>
            <div className={style.text}>
              <p className={style.plink}>Forgot Password</p>
              <div>
                Need an account?&nbsp;
                <AuthType goToMenu="Signup">click here</AuthType>
              </div>
            </div>
          </div>
        </div>
      </CSSTransition>
    );
  }


  function Signup() {
    return (
      <CSSTransition in={activeMenu === "Signup"} unmountOnExit timeout={500}>
        <div ref={domNode}>
          <div className={style.signUp}>
            <div className={style.title}> Clip It</div>
            <Form label="First Name" type="text" />
            <Form label="Last Name" type="Text" />
            <Form label="Email" type="email" />
            <Form label="Date of Birth" type="date" />
            <Form label="Password" type="password" />
            <Form label="Confirm Password" type="password" />
            <div className={style.button}>
              <input type="submit" value="Sign Up" />
            </div>
            <div className={style.text}>
              have an&nbsp;
              <AuthType goToMenu="main"> account</AuthType>
            </div>
          </div>
        </div>
      </CSSTransition>
    );
  }
}
let useClickOutside = (handler) => {
  let domNode = useRef();

  useEffect(() => {
    let clickListener = (event) => {
      if (domNode.current && !domNode.current.contains(event.target)) {
        handler();
      }
    };

    document.addEventListener("mousedown", clickListener);

    return () => {
      document.removeEventListener("mousedown", clickListener);
    };
  });
  return domNode;
};

function Form(props) {
  return (
    <div className={style.formBox}>
      <label className={style.label}>{props.label}:</label>

      <form className={style.input}>
        <input 
          type={props.input} 
          name={props.input} 
          required="true" />
      </form>
    </div>
  );
}

function Emailform(props) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  return (
    <div className={style.formBox}>
      <label className={style.label}>{props.label}:</label>

      <form className={style.input}>
        <input 
          type="email" 
          name={props.input} 
          required="true"
          value={email} 
          onChange={(e) => setEmail(e.target.value)} />
      </form>
    </div>
  );
}

function Passform(props) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  return (
    <div className={style.formBox}>
      <label className={style.label}>{props.label}:</label>

      <form className={style.input}>
        <input 
          type="text" 
          name={props.input} 
          required="true"
          value={password} 
          onChange={(e) => setPassword(e.target.value)} />
      </form>
    </div>
  );
}

Firebase.js

import firebase from 'firebase/app';
//import * as firebase from "firebase/app";
import "firebase/auth"
import "firebase/firestore"

// For Firebase JS SDK v7.20.0 and later, measurementId is optional 
const firebaseConfig = {
  apiKey: "AIzaSyCq8BAlTWJXG7rFU95QkUTU8U0kXruPA9o",
  authDomain: "clip-it-70ff5.firebaseapp.com",
  databaseURL: "https://clip-it-70ff5-default-rtdb.firebaseio.com",
  projectId: "clip-it-70ff5",
  storageBucket: "clip-it-70ff5.appspot.com",
  messagingSenderId: "637963668511",
  appId: "1:637963668511:web:9cbd1deae03b819153d92a",
  measurementId: "G-8S1G78ZH49"
};

const app = !firebase.apps.length ? firebase.initializeApp(firebaseConfig) : firebase.app();

const auth = app.auth();
const db = app.firestore();

/* Using Google Authentication */
const googleProvider = new firebase.auth.GoogleAuthProvider();
//
  const signInWithGoogle = async () => {
    try {
      const res = await auth.signInWithPopup(googleProvider);
      const user = res.user;
      const query = await db
        .collection("users")
        .where("uid", "==", user.uid)
        .get();
      if (query.docs.length === 0) {
        await db.collection("users").add({
          uid: user.uid,
          name: user.displayName,
          authProvider: "google",
          email: user.email,
        });
        alert("You're logged in");
      }
    } catch (err) {
      console.error(err);
      alert(err.message);
    }
  };


  /* Using Email and Password */
  // Sign/Logging In
  const signInWithEmailAndPassword = async (email, password) => {
    try {
      await auth.signInWithEmailAndPassword(email.trim(), password);
      alert("You've logged in successfuly");
    } catch (err) {
      console.error(err);
      alert("The email or password is incorrect, please try again");
    }
  };

  //SigningUp
  const registerWithEmailAndPassword = async (name, email, password) => {
    try {
      const res = await auth.createUserWithEmailAndPassword(email.trim(), password);
      const user = res.user;
      await db.collection("users").add({
        uid: user.uid,
        name,
        authProvider: "local",
        email,
      });
    } catch (err) {
      console.error(err);
      alert(err.message);
    }
  };

  //Sending Password reset link
  const sendPasswordResetEmail = async (email) => {
    try {
      await auth.sendPasswordResetEmail(email);
      alert("Password reset link sent!");
    } catch (err) {
      console.error(err);
      alert(err.message);
    }
  };

  const logout = () => {
    auth.signOut();
  }; // Log out

  export {
    signInWithGoogle,
    signInWithEmailAndPassword,
    registerWithEmailAndPassword,
    sendPasswordResetEmail,
    logout,
    auth,
    db,
  };

  

您的代码有一个问题列表。

  1. 您在 EmailForm/PassForm 以及父 (Auth) 组件中都有电子邮件/密码状态。
  2. 您正在设置值并尝试处理 EmailForm/PassForm 组件上的 onChange,但您从未真正调用过这些道具,并且您从未真正设置过您尝试访问的某些道具(例如:name={props.input} )。
  3. 这两个组件中的输入将电子邮件/密码状态设置为自己,但您的 Auth 组件正在为 Firebase 提供自己的电子邮件/密码状态,而您实际上从未设置过这些状态。

您也不应该对密码字段使用 type="text" 输入。

如果您坚持保留您当前拥有的结构,请将 EmailForm 和 PassForm 函数内部移动到您的 Auth 组件中,删除您在它们上设置的 props,删除它们的状态,然后只使用 Auth 组件的状态。

// Inside the Auth component
const EmailForm = () => {
  return (
    <div className={style.formBox}>
      <label className={style.label}>{props.label}:</label>

      <form className={style.input}>
        <input 
          type="email" 
          name="email"
          required="true"
          value={email} 
          onChange={(e) => setEmail(e.target.value)} />
      </form>
    </div>
  );
}

const PassForm = () => {
  return (
    <div className={style.formBox}>
      <label className={style.label}>{props.label}:</label>

      <form className={style.input}>
        <input 
          type="password"
          name="password"
          required="true"
          value={password} 
          onChange={(e) => setPassword(e.target.value)} />
      </form>
    </div>
  );
}

然后用一个简单的方法调用它们

<EmailForm />
<PassForm />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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