Firebase Auth,React JS,错误:“登录不是函数”

问题描述 投票:0回答:1

firebaseConfig.js

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
import { getAuth } from "firebase/auth";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_FIREBASE_DATABASE_URL,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
  measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const analytics = getAnalytics(app);
export const auth = getAuth(app);

export default app;

AuthContext.js

import { createContext, useContext, useEffect, useState } from "react";
import {
  signInWithEmailAndPassword,
  signOut,
  onAuthStateChanged,
} from "firebase/auth";
import { auth } from "../firebaseConfig";

const AuthContext = createContext();

export const AuthContextProvider = ({ children }) => {
  const [user, setUser] = useState({});
  const logIn = (email, password) => {
    return signInWithEmailAndPassword(auth, email, password);
  };
  const logOut = () => {
    return signOut(auth);
  };
  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
      console.log(currentUser);
      setUser(currentUser);
    });
    return () => {
      unsubscribe();
    };
  }, []);
  return (
    <AuthContext.Provider value={{ user, logIn, logOut }}>
      {children}
    </AuthContext.Provider>
  );
};

export const UserAuth = () => {
  return useContext(AuthContext);
};

Login.jsx(此处出现错误)

import React, { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { UserAuth } from "../context/AuthContext";

const Login = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState("");
  const navigate = useNavigate();
  const { logIn } = UserAuth() | {};

  const handleSubmit = async (e) => {
    e.preventDefault();
    setError("");
    try {
      await logIn(email, password);
      navigate("/account");
    } catch (e) {
      setError(e.message); // <--- This is the line where the error happens
      console.log(e.message);
    }
  };

  return (
    <div className="max-w-[600px] mx-auto my-16 p-4">
      <div>
        <h1 className="text-2xl font-bold py-2">Login to your Account</h1>
      </div>
      <form onSubmit={handleSubmit}>
        <div className="flex flex-col py-2">
          <label className="py-2 font-medium">Email Address</label>
          <input
            input
            onChange={(e) => setEmail(e.target.value)}
            className="border p-2"
            type="email"
          />
        </div>
        <div className="flex flex-col py-2">
          <label className="py-2 font-medium">Password</label>
          <input
            onChange={(e) => setPassword(e.target.value)}
            className="border p-2"
            type="password"
          />
        </div>
        <button className="border border-blue-500 bg-blue-600 hover:bg-blue-500 w-full p-4 my-12 text-white">
          Log In
        </button>
      </form>
    </div>
  );
};

export default Login;

package.json

{
  "name": "sa_react_firebase_database",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "dotenv": "^16.4.5",
    "firebase": "^10.12.2",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-router-dom": "^6.23.1",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "autoprefixer": "^10.4.19",
    "postcss": "^8.4.38",
    "tailwindcss": "^3.4.4"
  }
}

我正在使用 React JS 和 Firebase Auth 尝试创建一个简单的电子邮件身份验证系统,请按照此处的视频指南进行操作:

https://youtu.be/x62aBvnRCKw?si=YGSjcsdjz5Zsb6Y-

但是,我收到错误:“logIn is not a function”,这是 Login.jsx 中的 handleSubmit 中的捕获错误。我尝试从视频上传者的 GitHub 克隆存储库,尽管在 handleSubmit 中没有逻辑差异,但他们的代码工作得很好,所以我怀疑问题出在其他地方。

我在提交之前查看了类似的帖子,但我发现答案要么含糊不清,要么无法解决这些帖子中提出的问题。

希望我们能在这里得到一些具体的答案,以便将来搜索此问题的人们可以更轻松地设置 Firebase 身份验证系统。

javascript reactjs firebase firebase-authentication
1个回答
0
投票

此错误通常是由于以下原因之一造成的:

登录功能未正确提供或从 AuthContext 访问。 AuthContext 提供程序未包装 Login 组件,因此 Login 组件无权访问 logIn 函数。 您使用登录功能的方式可能存在拼写错误或语法问题。

分步解决方案

  1. 确保 AuthContextProvider 包装您的应用程序

AuthContextProvider 必须包装需要访问登录功能的组件。通常,您会在 AuthContextProvider 中包装整个应用程序或至少包装需要身份验证的组件。

App.js 中的示例:

import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { AuthContextProvider } from './context/AuthContext';
import Login from './components/Login';
import Account from './components/Account'; // Example account page

function App() {
  return (
    <AuthContextProvider>
      <Router>
        <Routes>
          <Route path="/login" element={<Login />} />
          <Route path="/account" element={<Account />} /> {/* Example route */}
        </Routes>
      </Router>
    </AuthContextProvider>
  );
}

export default App;

在此设置中,AuthContextProvider 包装路由器,确保所有路由(包括登录)都可以访问上下文。

  1. 验证 Login.jsx 中的 UserAuth 函数使用情况

确保您正确使用 UserAuth 挂钩从上下文访问登录函数。 { 登录 } = UserAuth() || {} 确保即使 UserAuth 返回未定义,解构也不会失败。

Login.jsx 中的示例:

import React, { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { UserAuth } from '../context/AuthContext';

const Login = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState("");
  const navigate = useNavigate();
  const { logIn } = UserAuth() || {};  // Ensures logIn is safely destructured

  const handleSubmit = async (e) => {
    e.preventDefault();
    setError("");
    try {
      await logIn(email, password);
      navigate("/account");
    } catch (e) {
      setError(e.message);
      console.log(e.message);
    }
  };

  return (
    <div className="max-w-[600px] mx-auto my-16 p-4">
      <div>
        <h1 className="text-2xl font-bold py-2">Login to your Account</h1>
      </div>
      <form onSubmit={handleSubmit}>
        <div className="flex flex-col py-2">
          <label className="py-2 font-medium">Email Address</label>
          <input
            onChange={(e) => setEmail(e.target.value)}
            className="border p-2"
            type="email"
          />
        </div>
        <div className="flex flex-col py-2">
          <label className="py-2 font-medium">Password</label>
          <input
            onChange={(e) => setPassword(e.target.value)}
            className="border p-2"
            type="password"
          />
        </div>
        <button className="border border-blue-500 bg-blue-600 hover:bg-blue-500 w-full p-4 my-12 text-white">
          Log In
        </button>
      </form>
    </div>
  );
};

export default Login;
  1. 调试 AuthContext 初始化

确保正确定义 AuthContext 及其中提供的功能(logIn 和 logOut),并且不会错误地排除。另外,请确保从 firebaseConfig.js 正确导入身份验证。

AuthContext.js 示例:

import { createContext, useContext, useEffect, useState } from "react";
import {
  signInWithEmailAndPassword,
  signOut,
  onAuthStateChanged,
} from "firebase/auth";
import { auth } from "../firebaseConfig";

const AuthContext = createContext();

export const AuthContextProvider = ({ children }) => {
  const [user, setUser] = useState({});
  
  const logIn = (email, password) => {
    return signInWithEmailAndPassword(auth, email, password);
  };

  const logOut = () => {
    return signOut(auth);
  };

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
      setUser(currentUser);
    });
    return () => {
      unsubscribe();
    };
  }, []);

  return (
    <AuthContext.Provider value={{ user, logIn, logOut }}>
      {children}
    </AuthContext.Provider>
  );
};

export const UserAuth = () => {
  return useContext(AuthContext);
};

希望对你有帮助

© www.soinside.com 2019 - 2024. All rights reserved.