I am using firebase authentication in my react application for sign-in users but when i entered my email which is 'namangarg82#gmail.com' and Click on Sign in button it shows an error:- Cannot create property '_canInitEmulator' on string 'namangarg82#gmail.com'
My Signup.js file
import React, { useContext, useRef,useState} from 'react'
import { Form, Button, Card,Alert } from 'react-bootstrap'
import { useAuth } from './AuthContext';
import { AuthProvider } from './AuthContext';
export function Signup() {
const emailRef=useRef();
const passwordRef=useRef();
const passwordConfirmRef=useRef();
const { signup } =useAuth()
const [error,setError]=useState('')
const [loading,setLoading]=useState(false)
console.log(error,"12",loading);
console.log(useAuth(),"ji")
// const{a}=useContext(AuthProvider);
// console.log(a);
async function handleSubmit(e){
e.preventDefault()
if(passwordRef.current.value!==passwordConfirmRef.current.value)
{
console.log(passwordRef.current.value);
return setError("Passwords do not match")
}
try{
console.log("try");
setLoading(true);
setError("");
console.log(emailRef.current.value,passwordRef.current.value);
await signup(emailRef.current.value,passwordRef.current.value)
} catch(err){
console.log("hi",err);
setError("Failed to create an account")
}
setLoading(false);
console.log(loading,"8");
}
return (
<div>
<Card>
<Card.Body className="text-center mb-4">
<h2>SignUp</h2>
{error && <Alert variant="danger">{error}</Alert>}
<Form onSubmit={(e)=>{handleSubmit(e)} }>
<Form.Group id="email">
<Form.Label>Email</Form.Label>
<Form.Control type="email" ref={emailRef}>
</Form.Control>
</Form.Group>
<Form.Group id="password">
<Form.Label>Password</Form.Label>
<Form.Control type="password" ref={passwordRef}>
</Form.Control>
</Form.Group>
<Form.Group id="passwordConfirm">
<Form.Label>Password Confirmation</Form.Label>
<Form.Control type="password" ref={passwordConfirmRef}>
</Form.Control>
</Form.Group>
<Button disabled={loading} type="submit" className="w-100">Sign Up</Button>
</Form>
</Card.Body>
</Card>
</div>
)
}
export default Signup
My Authcontext file
import React,{createContext,useContext,useState,useEffect} from 'react'
import {auth} from '../Firebase'
import { createUserWithEmailAndPassword} from "firebase/auth";
// const AuthContext =React.createContext()
const AuthContext =createContext()
export function useAuth(){
return useContext(AuthContext)
}
export function AuthProvider({children}) {
const [currentUser,setCurrentUser]=useState()
function signup(email,password){
return createUserWithEmailAndPassword(email,password)
}
useEffect(() => {
const unsuscribe = auth.onAuthStateChanged(user=>{
setCurrentUser(user)
})
return unsuscribe
}, [])
const value={
currentUser,
signup,
}
return (
<div>
< AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
</div>
)
}
export default AuthContext
and my firebase setup is
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
apiKey: "AIzaSyDLlZn08b5PlDpiqTQNxkyfpOPpz_6Gh8o",
authDomain: "portfolio-279ef.firebaseapp.com",
projectId: "portfolio-279ef",
storageBucket: "portfolio-279ef.appspot.com",
messagingSenderId: "778898179742",
appId: "1:778898179742:web:7beb09bf995e5041de1d8f"
};
const Firebaseapp = initializeApp(firebaseConfig);
export const auth=getAuth();
export default Firebaseapp;
Please help me
With new firebase functional approach, you need to include auth parameter like this:
createUserWithEmailAndPassword(auth, email, password)
In the firebase 9.0^, you try with this, in almost all methods, the auth method is inserted first, and import from your firebase setup.
//With your app initialized
import {getAuth} from 'firebase/auth'
...
const auth = getAuth()
return createUserWithEmailAndPassword(auth, email,password)
Source: https://firebase.google.com/docs/auth/web/password-auth?hl=pt
In your AuthContext file, createUserWithEmailAndPassword must include auth too:
createUserWithEmailAndPassword(auth, email, password)
Related
I am getting the following error while trying to import auth from firebase.js
Module not found: Error: You attempted to import /firebase/auth which falls outside of the project src/
directory. Relative imports outside of src/ are not supported.
You can either move it inside src/, or add a symlink to it from project's node_modules/.
However firebase.js is stored in the src directory and the file in which I have been trying to import is Register.jsx which is in the src/pages folder. I have been stuck on this for hours now. Any help would be appreciated.
firebase.js contents
import { initializeApp } from "firebase/app";
import { getAuth } from "/firebase/auth";
import { getStorage } from "firebase/storage";
const firebaseConfig = {
apiKey: "<API_KEY>",
authDomain: "chateapp.com",
projectId: "ch715c",
storageBucket: "chaom",
messagingSenderId: "4960541",
appId: "<APP_ID>"
};
// Initialize Firebase
export const app = initializeApp(firebaseConfig);
export const auth = getAuth();
export const storage = getStorage();
Register.js contents
import React from 'react'
import Add from "../img/addAvatar.png"
import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth";
import { auth, storage } from '../firebase'
import { useState } from 'react';
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
const Register = () => {
const [err, setErr] = useState(false)
const handleSubmit = async (e) => {
e.preventDefault()
const displayName = e.target[0].value;
const email = e.target[1].value;
const password = e.target[2].value;
const file = e.target[3].files[0];
try {
const res = await createUserWithEmailAndPassword(auth, email, password);
/** #type {any} */
const metadata = {
contentType: 'image/jpeg'
};
const storageRef = ref(storage, displayName);
const uploadTask = uploadBytesResumable(storageRef, file, metadata);
uploadTask.on('state_changed',
(error) => {
setErr(true);
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then(async(downloadURL) => {
await updateProfile(res.user, {
displayName,
photoURL:downloadURL,
});
});
}
);
}
catch (err) {
setErr(true)
}
}
return (
<div className='formContainer'>
<div className='formWrapper'>
<span className='logo'>Lambda Chat</span>
<span className='title'>Register</span>
<form onSubmit={handleSubmit}>
<input type="text" placeholder='display name' />
<input type="email" placeholder='email' />
<input type="password" placeholder='password' />
<input type="file" id='file' style={{ display: 'none' }} />
<label htmlFor="file">
<img src={Add} alt="" />
<span>Add an avatar</span>
</label>
<button>Sign Up</button>
{err && <span>Something went wrong!</span>}
</form>
<p>Have an account? Login</p>
</div>
</div>
)
}
export default Register;
In the firebase.js remove the initial / from the getAuth import.
import { getAuth } from "/firebase/auth";
To:
import { getAuth } from "firebase/auth";
So, I'm able to create an account and to successfully get to the MyAccount page, see who's currently logged in to MyAccount page and log out of the MyAccount page (MyAccount.js).
However, when I try to log in using an email + password by pressing the Sign In button of the Body2.js, I can reach the MyAccount page but can't see who's logged in and I get the "User already Logged In!" error message.
Here's my firebase file:
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { createUserWithEmailAndPassword, getAuth, onAuthStateChanged, signOut, signInWithEmailAndPassword } from "firebase/auth";
import { useEffect, useState } from "react";
// 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: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
authDomain: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
projectId: "XXXXXXXXXXXXXXXXX",
storageBucket: "XXXXXXXXXXXXXXXXXXXXXXXXX",
messagingSenderId: "XXXXXXXXXXXXXXXXXXXXXXXX",
appId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
measurementId: "XXXXXXXXXXXXXXXXXXXXXXXXXX"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
export function signup(email, password) {
return createUserWithEmailAndPassword(auth, email, password);
}
export function logout() {
return signOut(auth);
}
export function login(email, password) {
return signInWithEmailAndPassword(auth, email, password);
}
// Custom Hook
export function useAuth() {
const [ currentUser, setCurrentUser ] = useState();
useEffect(() => {
const unsub = onAuthStateChanged(auth, user => setCurrentUser(user));
return unsub;
}, [])
return currentUser;
}
Here's my App.js file:
import React, { useState } from 'react';
import './App.css';
import Header from './Header';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import Menu from './Menu';
import HeaderBlock from './HeaderBlock';
import Header2 from './Header2';
import Body2 from './Body2';
import Footer2 from './Footer2';
import SignUp from './SignUp';
import MyAccount from './MyAccount' ;
function App() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
return (
<Router>
<div className="app">
<Switch>
<Route exact path='/'>
<Header isMenuOpen={isMenuOpen} setIsMenuOpen={setIsMenuOpen}/>
{isMenuOpen && <Menu/>}
<HeaderBlock />
</Route>
<Route exact path='/Login2'>
<Header2 />
<Body2 />
<Footer2 />
</Route>
<Route exact path='/signup'>
<Header2 />
<SignUp />
<Footer2 />
</Route>
<Route exact path='/MyAccount'>
<Header2 />
<MyAccount />
<Footer2 />
</Route>
</Switch>
</div>
</Router>
);
}
export default App;
Here's my signup file:
import './SignUp.css';
import React, { useState, useRef } from 'react';
import { useHistory } from 'react-router-dom';
import { signup, useAuth } from './firebase';
function SignUp() {
const history = useHistory();
const emailRef = useRef();
const passwordRef = useRef();
const [ loading, setLoading ] = useState(false);
const currentUser = useAuth();
async function handleSignup() {
setLoading(true);
try {
await signup(emailRef.current.value, passwordRef.current.value);
}
catch {
alert("Account already created/Credentials already used");
}
setLoading(false);
};
return (
<div className='signup'>
<div className='signup__info'>
<h1> Account Creation </h1>
<form className='signup__form'>
<label htmlFor='email'> Email Address </label>
<input
ref={emailRef}
placeholder=''
/>
<label htmlFor='email'> Password </label>
<input
ref={passwordRef}
type="password"
placeholder=""
/>
<div className='signupblock__actions'>
<button
className='signupblock__buttonPrimary'
disabled={ loading || currentUser }
onClick={() => {handleSignup(); history.push('/MyAccount');}}> Register </button>
<div className='signupblock__divider'>
<hr/> <span> OR </span> <hr/>
</div>
<button
className='signupblock__buttonSecondary'
onClick={() => {history.push('/');}}> Home </button>
</div>
</form>
</div>
</div>
);
};
export default SignUp;
Here's my Body2.js file:
import React, { useState, useRef } from 'react';
import { useHistory } from 'react-router-dom';
import './Body2.css';
import { useAuth, login } from './firebase';
function Body2() {
const history = useHistory()
const currentUser = useAuth();
const [ loading, setLoading ] = useState(false);
const emailRef = useRef();
const passwordRef = useRef();
async function handleLogin() {
setLoading(true);
try {
await login(emailRef.current.value, passwordRef.current.value);
}
catch {
alert("User already Logged In!");
}
setLoading(false);
};
return (
<div className='body2'>
<div className='login2__info'>
<h1> Sign In </h1>
<form className='login2__form'>
<label htmlFor='email'> Email Address </label>
<input
type='email'
id='email'
/>
<label htmlFor='email'> Password </label>
<input
type='password'
id='password'
/>
<div className='headerBlock2__actions'>
<button
className='headerBlock2__buttonPrimary'
disabled={ loading || currentUser }
onClick={() => {handleLogin(); history.push('/MyAccount');}} > Sign In </button>
<div className='login2__divider'>
<hr/> <span> OR </span> <hr/>
</div>
<button
className='headerBlock2__buttonSecondary'
onClick={() => {history.push('/signup');}}> Create Account </button>
</div>
</form>
</div>
</div>
)
}
export default Body2;
Here's my Account.js file:
import React, { useState } from 'react';
// import app from './firebase';
import './MyAccount.css';
import { logout, useAuth } from './firebase';
import { useHistory } from 'react-router-dom';
function Home() {
const history = useHistory();
const currentUser = useAuth();
const [ loading, setLoading ] = useState(false);
async function handleLogOut() {
setLoading(true);
try {
await logout();
}
catch {
alert("Couldn't Log Out Effectively");
}
setLoading(false);
}
return (
<div>
<h1> Home </h1>
<p> What's Up Everyone! </p>
<h2> Currently logged in as: { currentUser?.email } </h2>
<button
disabled={ loading }
onClick={() => {handleLogOut(); history.push('/');}}> Log Out </button>
</div>
);
}
export default Home;
I think I'm not resetting the current user value in Body2.js but I'm not sure or don't know how to.
I am writing a small CMS in react however I can't seem to run tests on any of my components.
For example I'd like to test this component which performs a signin with Firebase email/pw.
import {useContext} from "react";
import {UserContext} from "../context/userContext";
import {useNavigate} from "react-router-dom";
import {useForm} from "react-hook-form";
import {yupResolver} from '#hookform/resolvers/yup';
import * as yup from "yup";
const schema = yup.object({
loginEmail: yup.string().email().required(),
loginPw: yup.string().min(8).required(),
});
export default function SignIn() {
const {signIn} = useContext(UserContext);
const navigate = useNavigate();
const { register, handleSubmit, formState: {errors} } = useForm({
resolver: yupResolver(schema)
});
async function onSubmit(data) {
// console.log(data);
try {
const cred = await signIn(
data.loginEmail,
data.loginPw
);
navigate("/admin");
} catch {
alert("email and / or pw incorrect");
}
}
return (
<section>
<form onSubmit={handleSubmit(onSubmit)}>
<h1>Sign In</h1>
<div>
<label
htmlFor="loginEmail"
>Email</label>
<input
id="loginEmail"
type="email"
{...register("loginEmail")}
/>
<p>{errors.loginEmail?.message}</p>
</div>
<label
htmlFor="loginPw"
>Password</label>
<input
id="loginPw"
type="password"
{...register("loginPw")}
/>
<p>{errors.loginPw?.message}</p>
<button type="submit">Submit</button>
</form>
</section>
);
}
This is my test:
import {render, screen} from "#testing-library/react";
import user from "#testing-library/user-event";
import SignIn from "./SignIn";
import {UserContextProvider} from "../context/userContext";
import { act } from 'react-dom/test-utils';
import {BrowserRouter} from "react-router-dom";
test("sign in", () => {
act(() => {
render (
<BrowserRouter>
<UserContextProvider>
<SignIn />
</UserContextProvider>
</BrowserRouter>
);
})
const email = screen.getByRole('textbox', {
name: /email/i
});
user.type(email, "daniel#myemail.me");
});
No matter what I try - I always get the same error:
TestingLibraryElementError: Unable to find an accessible element with the role "textbox" and name /email/i
Any idea what I am doing wrong?
I am working on a basic CRUD TODO list using React and Firebase. Everything works fine with the app, but when I want to use environment variables, the app cant load the history of todos that I previously added. It still runs as usual, but the when I refresh the page there seems to be no history of the TODOs I added. Furthermore, when I remove the environmental variables, and just use the credentials, the app brings up the previous history and works as it's supposed to.
These are the files. I already installed dotenv just to let you know.
firebase.js
import firebase from "firebase";
require("dotenv").config();
const firebaseApp = firebase.initializeApp({
apiKey: process.env.NEXT_PUBLIC_API_KEY,
authDomain: process.env.NEXT_PUBLIC_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_MESSAGE_SENDER_ID,
appId: process.env.NEXT_PUBLIC_APP_ID,
});
const db = firebaseApp.firestore();
export default db;
app.js
import React, { useState, useEffect } from "react";
import "./App.css";
import Todo from "./Todo";
import Button from "#material-ui/core/Button";
import FormControl from "#material-ui/core/FormControl";
import Input from "#material-ui/core/Input";
import InputLabel from "#material-ui/core/InputLabel";
import db from "./firebase";
import firebase from "firebase";
require("dotenv").config();
function App() {
const [todos, setTodos] = useState([]);
const [inputs, setInputs] = useState("");
useEffect(() => {
db.collection("todos")
.orderBy("timestamp", "desc")
.onSnapshot((snapshot) => {
setTodos(
snapshot.docs.map((doc) => ({ id: doc.id, todo: doc.data().todo }))
);
});
}, []);
const addToDo = (event) => {
event.preventDefault();
db.collection("todos").add({
todo: inputs,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
});
setInputs("");
};
return (
<div className="App">
<h1>Hello</h1>
<form>
<FormControl>
<InputLabel>Write a to do</InputLabel>
<Input
type="text"
value={inputs}
onChange={(event) => setInputs(event.target.value)}
/>
</FormControl>
<Button
disabled={!inputs}
variant="contained"
color="primary"
type="submit"
onClick={addToDo}
>
Add to do
</Button>
</form>
<ul>
{todos.map((todo) => (
<Todo todo={todo} />
))}
</ul>
</div>
);
}
export default App;
I have a react app and I have added firebase to it. The Sign Up creates a new user account but since the user has to be tracked I have gotten the user's id token and added it to local storage. It then takes the user to a dashboard page with the route link "/dashboard" but anyone can go to that link without signing up, it takes the id token kept in local storage, it then uses firebase admin to verify the id. If the verification is a success, it loads the page. Else it redirects the user to the login page. However when I created a new account, I got directed to the dashboard, and then redirected back to the login page. The id token had been correctly put into the local storage and the account had been created, but I got the error Failed to determine project ID: Error while making request: Failed to fetch. Error code: undefined at FirebaseAppError.FirebaseError [as constructor] (error.js:44) at FirebaseAppError.PrefixedFirebaseError [as constructor] (error.js:90) at new FirebaseAppError (error.js:125) at credential-internal.js:183.Here is my code:
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import firebase from "firebase/app";
import admin from "firebase-admin";
const firebaseConfig = {
// In the actual code I have set all of them
}
firebase.initializeApp(firebaseConfig);
admin.initializeApp();
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Signup.js:
import React, { useState, useEffect } from "react";
import { useHistory, Link } from "react-router-dom";
import firebase from "firebase";
import admin from "firebase-admin";
function Signup() {
const [userInfo, setUserInfo] = useState({email: "", username: "", password: ""});
const [errorMessage, setErrorMessage] = useState();
const [idToken, setIdToken] = useState();
const history = useHistory();
useEffect(() => {
setIdToken(localStorage.getItem("idToken"));
if (idToken !== undefined && idToken !== null) {
admin.auth().verifyIdToken(idToken)
.then(() => {
history.push("/dashboard");
})
.catch(() => {
localStorage.removeItem("idToken");
})
}
}, []);
const getText = ({target}) => {
setUserInfo({...userInfo, [target.name]: target.value});
}
const signup = (e) => {
e.preventDefault();
const {username, email, password} = userInfo;
if (username === "" || email === "" || password === "") {
setErrorMessage("Username, Email and Password cannot be empty.");
} else if (password.length < 8) {
setErrorMessage("Password cannot be less than 8 characters long.");
} else {
firebase.auth().createUserWithEmailAndPassword(email, password)
.then((userCredential) => {
userCredential.user.updateProfile({
displayName: username
})
userCredential.user.getIdToken()
.then((idToken) => {
localStorage.setItem("idToken", idToken);
history.push("/dashboard");
})
})
.catch((error) => {
setErrorMessage(error.message);
})
}
}
return(
<div>
<form onSubmit={signup}>
<input
type="email"
name="email"
placeholder="Email"
onChange={getText}
/>
<br />
<input
type="text"
name="username"
placeholder="Username"
onChange={getText}
/>
<br />
<input
type="password"
name="password"
placeholder="Password"
onChange={getText}
/>
<br />
<p>{errorMessage}</p>
<input type="submit" value="Sign Up" />
<p>Already have an account? <Link to="/login">Log In</Link></p>
</form>
</div>
);
}
export default Signup;
Dashboard.js:
import React, { useEffect } from "react";
import { useHistory } from "react-router-dom";
import admin from "firebase-admin";
function Dashboard() {
const history = useHistory();
useEffect(() => {
const idToken = localStorage.getItem("idToken");
if (idToken !== undefined && idToken !== null) {
admin.auth().verifyIdToken(idToken)
.catch((error) => {
console.log(error);
localStorage.removeItem("idToken");
history.push("/login");
})
} else {
localStorage.removeItem("idToken");
history.push("/login");
}
}, []);
return <h1>Dashboard</h1>
}
export default Dashboard;
Firebase-admin example initialization (it's different from firebase client side)
let admin = require('firebase-admin')
let serviceAccount = require('./theserviceaccountfile.json');
let db
module.exports = async function() {
if (!admin.apps.length) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://project-id.firebaseio.com",
})
if (!db) {
db = admin.database()
}
}
return db
}