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 (The error appears here)
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"
}
}
I’m using React JS and Firebase Auth to attempt to create a simple email authentication system, following a video guide here:
https://youtu.be/x62aBvnRCKw?si=YGSjcsdjz5Zsb6Y-
However, I get the error: "logIn is not a function", which is a catch error in handleSubmit in Login.jsx. I tried cloning the repo from the video uploader’s GitHub and their code works just fine, despite having no logic difference in handleSubmit, so I suspect the issue lies elsewhere.
I look at similar posts before submitting, but I found out that the answers were either vague, or weren’t able to solve the question asked in those posts.
Hopefully we can get some concrete answers here so that future folks who Google for this issue can have an easier time for setting up a firebase authentication system.
Edit: Thanks for the answer, the issue has been fixed! Initially I let "logIn" return an undefined so that the destructuring won’t fail, but that made React thinks it was not a function. Wrapping App.js in "AuthContextProvider" and then removing the undefined from "logIn" fixed the problem!
2
Answers
This error usually happens due to one of the following reasons:
The logIn function is not correctly provided or accessed from the AuthContext.
The AuthContext provider is not wrapping the Login component, so the Login component does not have access to the logIn function.
There might be a typo or syntax issue in how you’re using the logIn function.
Step-by-Step Solution
The AuthContextProvider must wrap around the components that need to access the logIn function. Typically, you would wrap your entire application or at least the components needing authentication in the AuthContextProvider.
Example in App.js:
In this setup, AuthContextProvider wraps the Router, ensuring that all routes, including Login, have access to the context.
Ensure you are correctly using the UserAuth hook to access the logIn function from the context. The { logIn } = UserAuth() || {} ensures that even if UserAuth returns undefined, the destructuring won’t fail.
Example in Login.jsx:
Ensure AuthContext and the functions provided within it (logIn and logOut) are correctly defined and not mistakenly excluded. Also, ensure that auth is correctly imported from firebaseConfig.js.
Example AuthContext.js:
I hope it helps
In. App.js, I wrap AuthProvider which is Context… around the whole routing.
This AuthProvider is from AuthProvider.js