"login" is a function from React context. This gives me an error:
const handleLogin = async (data: LoginType) => {
try {
await login(auth, data.email, data.password);
router.push("/Dashboard");
} catch (error: any) {
console.log(error.message);
}
Login.tsx?cd12:54 Firebase: Error (auth/invalid-value-(email),-starting-an-object-on-a-scalar-field). -- Full stack trace at bottom
But if I change it to the following, it works (signInWithEmailAndPassword is from firebase/auth):
const handleLogin = async (data: LoginType) => {
try {
await signInWithEmailAndPassword(auth, data.email, data.password);
router.push("/Dashboard");
} catch (error: any) {
console.log(error.message);
}
I did a console.log on the function parameters and they are identical in both cases. This leads me to believe that I'm doing something syntactically wrong with the React context. I looked at a few tutorials and SOF posts but am not sure how to fix my syntax.
I add the context "AuthContextProvider" in:
_app.tsx
import { AuthContextProvider } from "../config/AuthContext";
export default function App(props: AppProps & { colorScheme: ColorScheme }) {
const { Component, pageProps } = props;
};
return (
<AuthContextProvider>
<Head>
<title>Awesome App</title>
</Head>
<NotificationsProvider>
<Component {...pageProps} />
</NotificationsProvider>
</AuthContextProvider>
);
}
App.getInitialProps = async (appContext: AppContext) => {
const appProps = await NextApp.getInitialProps(appContext);
return { ...appProps };
};
This is the context:
AuthContext.tsx
import React, { createContext, useContext, useEffect, useState } from "react";
import {
onAuthStateChanged,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
} from "firebase/auth";
import { auth } from "./firebase";
interface UserType {
email: string | null;
uid: string | null;
}
const AuthContext = createContext({});
export const useAuth = () => useContext<any>(AuthContext);
export const AuthContextProvider = ({ children }: { children: React.ReactNode }) => {
const [user, setUser] = useState<UserType>({ email: null, uid: null });
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
if (user) {
setUser({
email: user.email,
uid: user.uid,
});
} else {
setUser({ email: null, uid: null });
}
});
setLoading(false);
return () => unsubscribe();
}, []);
const register = (email: string, password: string) => {
return createUserWithEmailAndPassword(auth, email, password);
};
const login = (email: string, password: string) => {
return signInWithEmailAndPassword(auth, email, password);
};
return (
<AuthContext.Provider value={{ user, register, login, logout }}>
{loading ? null : children}
</AuthContext.Provider>
);
};
This is my login component:
Login.tsx
import { auth } from "../../config/firebase";
import { useAuth } from '../../config/AuthContext';
import { signInWithEmailAndPassword } from 'firebase/auth';
export function AuthenticationForm(props: PaperProps) {
const handleLogin = async (data: LoginType) => {
console.log(type);
try {
await login(auth, data.email, data.password);
router.push("/Dashboard");
} catch (error: any) {
console.log(error.message);
}
return (
...
<form onSubmit = { form.onSubmit(handleLogin) }>
...
};
}
Stack trace:
POST https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=AIzaSyCsRsNM7xW05sufMo7bwOWo-gnSLFlwILU 400
eval @ index-c6def6da.js?a9e1:933
await in eval (async)
_performFetchWithErrorHandling @ index-c6def6da.js?a9e1:943
_performApiRequest @ index-c6def6da.js?a9e1:914
_performSignInRequest @ index-c6def6da.js?a9e1:988
signInWithPassword @ index-c6def6da.js?a9e1:2885
_getIdTokenResponse @ index-c6def6da.js?a9e1:3007
_processCredentialSavingMfaContextIfNecessary @ index-c6def6da.js?a9e1:4575
_signInWithCredential @ index-c6def6da.js?a9e1:4716
signInWithCredential @ index-c6def6da.js?a9e1:4735
signInWithEmailAndPassword @ index-c6def6da.js?a9e1:5106
login @ AuthContext.tsx?c53f:44
eval @ Login.tsx?cd12:51
step @ tslib.es6.js?37cc:102
eval @ tslib.es6.js?37cc:83
asyncGeneratorStep @ _async_to_generator.mjs?c03f:3
_next @ _async_to_generator.mjs?c03f:25
eval @ _async_to_generator.mjs?c03f:32
eval @ _async_to_generator.mjs?c03f:21
handleLogin @ Login.tsx?cd12:45
eval @ use-form.js?d6c0:156
callCallback @ react-dom.development.js?ac89:4164
invokeGuardedCallbackDev @ react-dom.development.js?ac89:4213
invokeGuardedCallback @ react-dom.development.js?ac89:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js?ac89:4291
executeDispatch @ react-dom.development.js?ac89:9041
processDispatchQueueItemsInOrder @ react-dom.development.js?ac89:9073
processDispatchQueue @ react-dom.development.js?ac89:9086
dispatchEventsForPlugins @ react-dom.development.js?ac89:9097
eval @ react-dom.development.js?ac89:9288
batchedUpdates$1 @ react-dom.development.js?ac89:26140
batchedUpdates @ react-dom.development.js?ac89:3991
dispatchEventForPluginEventSystem @ react-dom.development.js?ac89:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js?ac89:6465
dispatchEvent @ react-dom.development.js?ac89:6457
dispatchDiscreteEvent @ react-dom.development.js?ac89:6430
Login.tsx?cd12:54 Firebase: Error (auth/invalid-value-(email),-starting-an-object-on-a-scalar-field).
CodePudding user response:
In your context login
function:
const login = (email: string, password: string) => {
return signInWithEmailAndPassword(auth, email, password);
};
you are expecting an email and password only, but in your component, you are giving auth
as first argument.
await login(auth, data.email, data.password);