Attempted import error: 'signInUserWithEmailAndPassword' is not exported from 'firebase/auth' - firebase-authentication

please i need your help
I'm using Firebase 9.02 and i'm facing a problem when i try to import signInUserWithEmailAndPassword to sign in my users with Firebase authentication module
Is it a problem in the version 9 of Firebase ?
Thank you in advance
import React, { useRef } from "react";
import "./SignUpScreen.css";
import auth from "../firebase";
import {
createUserWithEmailAndPassword,
signInUserWithEmailAndPassword,
} from "firebase/auth";
// import auth from "../firebase";
const SignUpScreen = () => {
const emailRef = useRef(null);
const passwordRef = useRef(null);
const signIn = (e) => {
e.preventDefault();
signInUserWithEmailAndPassword(auth, emailRef, passwordRef)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
// ...
})
.catch((error) => {
alert(error);
});
};
return (
<div className='signupScreen'>
<form>
<h1>Sign In</h1>
<input
ref={emailRef}
className='signin'
type='email'
placeholder='Email'
/>
<input
ref={passwordRef}
className='signin'
type='password'
placeholder='Password'
/>
<button onClick={signIn} className='signin' type='submit'>
Sign In
</button>
</form>
</div>
);
};
export default SignUpScreen;```

No, the error is not a problem with version 9 of the Firebase SDK.
The issue is that the method is wrongly spelt.
It's signInWithEmailAndPassword and not signInUserWithEmailAndPassword.
Checkout the documentation

Related

update MainLayout.vue element in Quasar dynamically

I'm using Quasar Framework in which I'm trying to update an element on the MainLayout.vue layout component based on whether the user is logged in or not. I'm unable to get the login icon/button to change once I login to the site via a Login.vue component. I tried using provide/inject in the boot file to check if the user is logged in but it only updates after I refresh the whole page.
How do I get the login/logout q-btn to update dynamically based on the user login event from the Login.vue component?
Please let me know if I need to provide additional information.
MainLayout.vue
<template>
<q-layout view="lHh Lpr lFf">
<q-header elevated>
<q-toolbar>
<q-toolbar-title>
<q-btn flat #click="$router.push('/')">
Homepage
</q-btn>
</q-toolbar-title>
<q-space />
<q-btn v-if="!userLoggedIn" icon="login" #click="router.push('/login')" />
<q-btn v-if="userLoggedIn" icon="logout" #click="logout" />
</q-toolbar>
</q-header>
<q-page-container>
<router-view />
</q-page-container>
</q-layout>
</template>
<script setup>
import { inject, ref } from "vue";
const userId = inject("userId", false);
const userLoggedIn = ref(userId);
</script>
Login.vue (only showing login related code)
import { inject, ref } from "vue";
const updateUserId = inject("updateLoginStatus");
const email = ref();
const password = ref();
const signInExistingUser = () => {
signInWithEmailAndPassword(auth, email.value, password.value)
.then(() => {
updateUserId(auth.currentUser.uid);
router.push("/");
})
.catch((error) => {
$q.notify({
// deal with error
});
});
};
boot.js
export default boot(async ({ app, router }) => {
const user = await getCurrentUser();
let userLoggedIn = ref(false);
const uid = ref(false);
if (user) {
userLoggedIn.value = true;
uid.value = user.uid;
}
const updateLoginStatus = (updatedUserId) => {
uid.value = updatedUserId;
userLoggedIn.value = !userLoggedIn.value;
console.log(userLoggedIn.value);
return userLoggedIn.value;
};
app.provide("updateLoginStatus", updateLoginStatus);
app.provide("userId", uid.value);
});

Problem with handling Browser Cookies in vue.js

Well, I have a problem with a plugin handling browser cookies in vue.js
I installed plugin and imported it in main.js. I configured it too like below:
import { createApp } from "vue";
import { createPinia } from "pinia";
import { globalCookiesConfig } from "vue3-cookies";
import App from "./App.vue";
import router from "./router";
import { useMainStore } from "#/stores/main.js";
import { useStyleStore } from "#/stores/style.js";
import { darkModeKey, styleKey } from "#/config.js";
import "./css/main.css";
globalCookiesConfig({
expireTimes: "30d",
path: "/",
domain: "",
secure: true,
sameSite: "None",
});
/* Init Pinia */
const pinia = createPinia();
/* Create Vue app */
createApp(App).use(router).use(pinia).mount("#app");
/* Init Pinia stores */
const mainStore = useMainStore(pinia);
const styleStore = useStyleStore(pinia);
/* Fetch sample data */
mainStore.fetch("clients");
mainStore.fetch("history");
/* App style */
styleStore.setStyle(localStorage[styleKey] ?? "basic");
/* Dark mode */
if (
(!localStorage[darkModeKey] &&
window.matchMedia("(prefers-color-scheme: dark)").matches) ||
localStorage[darkModeKey] === "1"
) {
styleStore.setDarkMode(true);
}
/* Default title tag */
const defaultDocumentTitle = "SOFT-KOMP";
/* Set document title from route meta */
router.afterEach((to) => {
document.title = to.meta?.title
? `${to.meta.title} — ${defaultDocumentTitle}`
: defaultDocumentTitle;
});
And In my LoginView.vue i inserted this line in function:
this.$cookies.set('hover-time','1s');
Unfortunately I receive this:
runtime-core.esm-bundler.js:218 Uncaught TypeError: Cannot read properties of undefined (reading '$cookies')
So this is my LoginView.vue file. And I tried to test some of other sessions and cookie plugins but results was always the same. PRobably Im not installing this plugin properly in the component or something?
<script setup>
import { reactive } from "vue";
import { useRouter } from "vue-router";
import { mdiAccount, mdiAsterisk } from "#mdi/js";
import SectionFullScreen from "#/components/SectionFullScreen.vue";
import CardBox from "#/components/CardBox.vue";
import FormCheckRadio from "#/components/FormCheckRadio.vue";
import FormField from "#/components/FormField.vue";
import FormControl from "#/components/FormControl.vue";
import BaseButton from "#/components/BaseButton.vue";
import BaseButtons from "#/components/BaseButtons.vue";
import LayoutGuest from "#/layouts/LayoutGuest.vue";
const form = reactive({
login: "john.doe",
pass: "highly-secure-password-fYjUw-",
remember: true,
});
const router = useRouter();
const submit = () => {
router.push("/dashboard");
};
const login = () =>{
this.$cookies.set('hover-time','1s');
}
</script>
<template>
<LayoutGuest>
<SectionFullScreen v-slot="{ cardClass }" bg="purplePink">
<CardBox :class="cardClass" is-form #submit.prevent="submit">
<FormField label="Login" help="Please enter your login">
<FormControl
v-model="form.login"
:icon="mdiAccount"
name="login"
autocomplete="username"
/>
</FormField>
<FormField label="Password" help="Please enter your password">
<FormControl
v-model="form.pass"
:icon="mdiAsterisk"
type="password"
name="password"
autocomplete="current-password"
/>
</FormField>
<FormCheckRadio
v-model="form.remember"
name="remember"
label="Remember"
:input-value="true"
/>
<template #footer>
<BaseButtons>
<BaseButton #click='login' type="submit" color="info" label="Login" />
<BaseButton to="/dashboard" color="info" outline label="Back" />
</BaseButtons>
</template>
</CardBox>
</SectionFullScreen>
</LayoutGuest>
</template>
Well, what you have to is, first import the use in your setup in your LoginView.vue:
import { useCookies } from "vue3-cookies";
Then you can use it like this:
const { cookies } = useCookies();
and then cookies is accessible across your setup.
See answer and comment if you need more info.

Integrating Google Sign-In into your web app - migrating to the new library

So am practicing building this app, and I have integrated a Google sign-in using the Google Developers console. The problem is that I am getting this error on my console:
{
"error": "idpiframe_initialization_failed",
"details": "You have created a new client application that uses libraries for user authentication or authorization that will soon be deprecated. New clients must use the new libraries instead; existing clients must also migrate before these libraries are deprecated. See the Migration Guide for more information."
}
When I click the sign-in button another error then prints on my console as a second error:
{
"error": "popup_closed_by_user"
}
This is how my Login.jsx file looks like
import React from 'react';
import { GoogleLogin } from 'react-google-login';
import { useNavigate } from 'react-router-dom';
import { FcGoogle } from 'react-icons/fc';
import shareVideo from '../assets/share.mp4';
import logo from '../assets/logowhite.png';
import { client } from '../client';
const Login = () => {
const navigate = useNavigate();
const responseGoogle= (response) => {`
console.log(response)
}
return (
<div className='flex justify-start items-center flex-col h-screen'>
<div className='relative w-full h-full'>
<video
src={shareVideo}
type='video/mp4'
loop
controls={false}
muted
autoPlay
className='w-full h-full object-cover'
/>
<div className='absolute flex flex-col justify-center items-center top-0 right-0 left-0 bottom-0 bg-blackoverlay'>
<div className='p-5' >
<img src={logo} width='130px' alt='logo' />
</div>
<div className='shadow-2xl' >
<GoogleLogin
clientId={process.env.REACT_APP_GOOGLE_API_TOKEN}
render={(renderProps) => (
<button
type='button'
className='bg-mainColor flex justify-center items-center p-3 rounded-lg cursor-pointer outline-none'
onClick={renderProps.onClick}
disabled={renderProps.disabled}
>
<FcGoogle className='mr-4' /> Sign in with Google
</button>
)}
onSuccess={responseGoogle}
onFailure={responseGoogle}
cookiePolicy='single_host_origin'
/>
</div>
</div>
</div>
</div>
)
}
export default Login
client.js
import sanityClient from '#sanity/client'
import imageUrlBuilder from '#sanity/image-url'
export const client = sanityClient({
projectId: process.env.REACT_APP_SANITY_PROJECT_ID,
dataset: 'production',
apiVersion: '2021-11-16',
useCdn: true,
token: process.env.REACT_APP_SANITY_TOKEN,
ignoreBrowserTokenWarning: true
})
const builder = imageUrlBuilder(client);
export const urlFor = (source) => builder.image(source);
App.js
import React from 'react'
import { Routes, Route, useNavigate } from 'react-router-dom';
import Login from './components/Login';
import Home from './container/Home';
const App = () => {
return (
<Routes>
<Route path="Login" element={<Login />} />
<Route path="/*" element={<Home />} />
</Routes>
)
}
export default App
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router} from 'react-router-dom'
import App from './App';
import './index.css';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Router>
<App/>
</Router>,
);
.env
REACT_APP_GOOGLE_API_TOKEN = /*Sorry cannot show the token to you*/.apps.googleusercontent.com
REACT_APP_SANITY_PROJECT_ID = /*same here*/
REACT_APP_SANITY_TOKEN = /*same here*/
Home.jsx
import React from 'react'
const Home = () => {
return (
<div>
Home
</div>
)
}
export default Home

Why does react router work on localhost but will not work after Heroku deployment?

there are a few posts like this and I have tried other solutions such as adding a .htaccess file, and adding 'process.env.PUBLIC_URL' ahead of each route to get the relative route location, but nothing seems to be working with the new react-router-dom package which has been released...
The application will load the '/' login page no problem on startup in heroku, and in there a direct will move to another page, however after successful login I use 'window.location.assign("/Home")' to try to auto navigate back to the home page. This gets a 404 error.
Similarly, manually adding locations into the top bar also give 404 errors..
I have tried the fixes provided in other posts, but they are all for the old react-router-dom package (before they moved away from switch and started using BrowserRouter).
Can anyone help figure out why my router won't identify addresses added to the window location??
The application is currently deployed at https://dashboard.heroku.com/apps/octowatch-scratch
App.js
import React from "react";
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { createTheme, ThemeProvider } from '#mui/material/styles';
import AboutKPI from './pages/AboutKPI';
import Login from './pages/Login';
import BreachComposition from './pages/BreachComposition';
import BreachesPerWard from './pages/BreachesPerWard';
import Dashboard from './pages/Dashboard';
import AddAccount from './pages/AddAccount';
import ManageAccounts from './pages/ManageAccounts';
import OverallBreaches from './pages/OverallBreaches';
import AddData from './pages/AddData';
import Home from './pages/Home';
import { lightGreen, brown } from '#mui/material/colors';
import './App.css';
const theme = createTheme({
palette: {
primary: {main: lightGreen[900]},
secondary: {main: brown[500]},
},
});
function App() {
return (
<BrowserRouter>
<ThemeProvider theme={theme}>
<Routes>
<Route exact path="/" element = {<Login/>} />
<Route exact path="/AboutKPI" element = {<AboutKPI/>} />
<Route exact path="/BreachComposition" element = {<BreachComposition/>} />
<Route exact path="/BreachesPerWard" element = {<BreachesPerWard/>} />
<Route exact path="/Login" element = {<Login/>} />
<Route exact path="/Home" element = {<Home/>} />
<Route exact path="/Dashboard" element = {<Dashboard/>} />
<Route exact path="/AddAccount" element = {<AddAccount/>} />
<Route exact path="/ManageAccounts" element = {<ManageAccounts/>} />
<Route exact path="/OverallBreaches" element = {<OverallBreaches/>} />
<Route exact path="/AddData" element = {<AddData/>} />
</Routes>
</ThemeProvider>
</BrowserRouter>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
Login Page ()
import React, { useState } from "react";
import { Grid,Paper, Avatar, TextField, Button, Typography } from '#mui/material'
import FormControlLabel from '#mui/material/FormControlLabel';
import Checkbox from '#mui/material/Checkbox';
import Api from "../api.js"
import LockIcon from '#mui/icons-material/Lock';
import { Link } from 'react-router-dom';
export default function Login(breachesCallback) {
const paperStyle={padding :20,height:'70vh',width:280, margin:"20px auto"}
const avatarStyle={backgroundColor:'#1bbd7e'}
const btnstyle={margin:'8px 0'}
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
var now = new Date();
function validateForm() {
return email.length > 0 && password.length > 0;
}
function goHome () {
window.location.assign("/Home");
}
function goReset () {
window.location.assign("/UpdatePassword");
}
function handleSubmit(event) {
Api.noToken().post('/users/login', {
email: email,
password: password,
resetDate: Math.floor(((now / 8.64e7) - 150.604166666))
})
.then(function (response) {
if(response.status === 204){//this means a password reset still needs to occur here
Api.withToken().get('/breaches/')
.then(res => {
breachesCallback(res.data);
console.log(res.data);
}).then(goReset());
}
else if(response.status === 200){
window.sessionStorage.setItem("token", response.data.token);
Api.withToken().get('/breaches/')
.then(res => {
breachesCallback(res.data);
console.log(res.data);
}).then(goHome());
}
})
.catch(function (error) {
alert("Invalid username or password")
});
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<Grid>
<Paper elevation={10} style={paperStyle}>
<Grid align='center'>
<Avatar style={avatarStyle}><LockIcon/></Avatar>
<h2>Sign In</h2>
</Grid>
<TextField label='Username' placeholder='Enter username' fullWidth required onChange={e => setEmail(e.target.value)}/>
<TextField label='Password' placeholder='Enter password' type='password' fullWidth required onChange={e => setPassword(e.target.value)}/>
<FormControlLabel
control={
<Checkbox
name="checkedB"
color="primary"
/>
}
label="Remember me"
/>
<Button type='submit' disabled={!validateForm()} color='primary' variant="contained" style={btnstyle} fullWidth>Sign in</Button>
<Typography >
<Link to="#" >
Forgot password ?
</Link>
</Typography>
<Typography > Do you have an account ?
<Link to="/AddAccount" >
Sign Up
</Link>
</Typography>
</Paper>
</Grid>
</form>
)
}
After hours of looking I've finally found the most up to date tool you are meant to use for react router in the latest update (currently 6.1.1)
This is about 3 posts down in this post (the other answers are all for older versions of react router and will not work)
The answer is simple:
import { useNavigate } from "react-router-dom";
then in your function add a simpler variable for useNavigate:
let navigate = useNavigate();
and replace your window.location.assign("/Home") with navigate("/Home", { replace: true });
(obviously could also just say useNavigate("/Home", {replace:true})

How do you implement AsynSelect with isMilti in Typescript? #react-select

I can't seem to get isMulti to work with Aysync select. I've tried a number of iterations but nothing works. Below is my code. Once I uncomment the isMulti line, thats whne things break. I tried to create a new array type to see if that helps but it doesn't.
I also have another issue where the options box doesn't load the options from the promise function but only does so when I delete a character from the input (it's using the cached results to populated the dropdown at that point).
import { useState } from 'react';
import { FunctionComponent } from 'react';
import AsyncSelect from 'react-select/async';
import ValueType from 'react-select';
import { getGoogleAutoComplete } from './services';
import map from '../../assets/map.svg';
import './LocationInput.styles.scss';
type OptionType = {
value: string;
label: string;
}
type OptionTypeArray = Array<OptionType>;
const LocationInput: FunctionComponent = () => {
const [locations, setLocations] = useState<ValueType<OptionType | OptionTypeArray>>();
const [query, setQuery] = useState("");
const handleChange = (option: ValueType<OptionType | OptionTypeArray> | null) => {
if (option != null){setLocations(option)};
console.log('im in handleChange!')
console.log(option)
};
async function promiseOptions(): Promise<any>{
return await getGoogleAutoComplete(query);
}
return (
<div className='location-input-container'>
<div className='map-icon'>
<img src={map} alt=''/>
</div>
<div className='location-input'>
<AsyncSelect
//isMulti={true}
cacheOptions
value={locations}
defaultOptions
placeholder='Enter a City or ZIP code'
onChange={(option) => handleChange(option)}
onInputChange={(value) => setQuery(value)}
closeMenuOnSelect={true}
noOptionsMessage={() => 'No Match Found'}
isClearable={true}
loadOptions={promiseOptions} />
</div>
</div>
)
}
export default LocationInput;
I was able to find a solution. However, I had to use Type Assertion to make it workout which isn't the ideal approach. If anyone has any other suggestions I'd greaty appreacite it.
import { useState, FunctionComponent } from 'react';
import AsyncSelect from 'react-select/async';
import { getGoogleAutoComplete } from './services';
import OptionTypeBase from 'react-select';
import { OptionsType } from 'react-select/src/types';
import makeAnimated from "react-select/animated";
import map from '../../assets/map.svg';
import './LocationInput.styles.scss';
const LocationInput: FunctionComponent = () => {
const [locations, setLocations] = useState<OptionsType<OptionTypeBase>>();
const [query, setQuery] = useState("");
const handleChange = (option: OptionsType<OptionTypeBase>) => {
setLocations(option);
console.log('im in handleChange!')
console.log(option)
};
async function promiseOptions(value:string): Promise<any>{
return new Promise(resolve => resolve(getGoogleAutoComplete(value)));
}
//get animated components wrapper
const animatedComponents = makeAnimated();
return (
<div className='location-input-container'>
<div className='map-icon'>
<img src={map} alt=''/>
</div>
<div className='location-input'>
<AsyncSelect
isMulti={true}
components={animatedComponents}
cacheOptions
placeholder='Enter a City or ZIP code'
onChange={(option) => handleChange(option as OptionsType<OptionTypeBase>)}
closeMenuOnSelect={true}
noOptionsMessage={() => 'No Match Found'}
loadOptions={promiseOptions} />
</div>
</div>
)
}
export default LocationInput;