How does Firebase phone number authentication work? - javascript

Firebase Phone number authentication not working. Upon submitting the form for entering the phone number, this is what the error shows: Google Sign in works but not the registration using Phone number.
Uncaught TypeError:
firebase_utils__WEBPACK_IMPORTED_MODULE_2_.auth.RecaptchaVerifier is not a function
import React, { useState, useEffect } from "react";
import { Button, TextField } from "#material-ui/core";
import { signInWithGoogle, firestore, auth } from "./../firebase/utils";
const Register = (props) => {
const [currentUser, setCurrentUser] = useState("");
const [displayName, setDisplayName] = useState("");
const [phoneNumber, setPhoneNumber] = useState("");
const [otp, setOtp] = useState("");
const getCurrentUser = () => {
auth.onAuthStateChanged((user) => {
if (user) {
const uid = user["uid"];
const name = user.displayName;
console.log("uid: ", uid);
console.log(name);
setCurrentUser(uid);
setDisplayName(name);
} else {
console.log("uid: ", "no uid");
}
});
};
useEffect(() => {
getCurrentUser();
}, []);
const configureCaptcha = () => {
window.recaptchaVerifier = auth.RecaptchaVerifier("sign-in-button", {
size: "invisible",
callback: (response) => {
// reCAPTCHA solved, allow signInWithPhoneNumber.
onSignInSubmit();
console.log("Verified");
},
defaultCountry: "PH",
});
};
const onSignInSubmit = (e) => {
e.preventDefault();
configureCaptcha();
const phoneNumber = phoneNumber;
console.log(phoneNumber);
const appVerifier = window.recaptchaVerifier;
auth
.signInWithPhoneNumber(phoneNumber, appVerifier)
.then((confirmationResult) => {
// SMS sent. Prompt user to type the code from the message, then sign the
// user in with confirmationResult.confirm(code).
window.confirmationResult = confirmationResult;
console.log("OTP has been sent");
// ...
})
.catch((error) => {
// Error; SMS not sent
// ...
console.log(error);
});
};
return (
<div>
<h1>Google SIGN IN</h1>
<Button variant="contained" onClick={signInWithGoogle}>
Google Sign In
</Button>
{auth.currentUser ? (
<div>
{" "}
<br />
UID: {currentUser}
<br />
Name: {displayName}
</div>
) : (
<div>
<h1>NOT LOGGED IN </h1>
<form onSubmit={onSignInSubmit}>
<div id="sign-in-button"></div>
<TextField
type="number"
name="mobile"
placeholder="mobile"
value={phoneNumber}
onChange={(e) => setPhoneNumber(e.target.value)}
/>
<Button type="submit">Submit</Button>
</form>
<h2>Enter OTP</h2>
<form>
<TextField
type="number"
name="OTP"
placeholder="Enter OTP"
value={otp}
onChange={(e) => setOtp(e.target.value)}
/>
<Button type="submit">Submit</Button>
</form>
</div>
)}
</div>
);
};
export default Register;

I doubt your code looks like this and that's incorrect:
const auth = firebase.auth()
window.recaptchaVerifier = auth.RecaptchaVerifier()
Try this instead
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier(...)
// ^^^^ not auth()

Related

FirebaseError: Firebase: Error (auth/user-token-expired) [duplicate]

This question already has an answer here:
firebase: admin.auth().updateUser() causes auth/user-token-expired
(1 answer)
Closed 8 months ago.
I have created a new form after creating a user with phone number authentication(in firebase), But an error keeps on coming after submitting FirebaseError: Firebase: Error (auth/user-token-expired)
The Error is Comming in this code
//This Component is used to store the Name ,Phone Number Of new User Which have Registered in SignUp With Number
import "./Auth.scss";
import React, { useState } from "react";
import { updateProfile, updateEmail } from "firebase/auth";
import { auth } from "../../firebase/config";
import { useNavigate, useLocation } from "react-router";
import usePhoneSignUp from "../../hooks/usePhoneSignUp";
import { update } from "lodash";
const SaveUserDetails = () => {
//code to extract userType after navigating from SignUpWithNumber page
const { state } = useLocation();
const userType = state.userType;
console.log(userType);
// .......
const {
signUp,
error: signupError,
isPending: signupIsPending,
} = usePhoneSignUp();
const [name, setname] = useState();
const [email, setemail] = useState();
const navigate = useNavigate();
const handleChange = (e) => {
e.preventDefault();
const { name, value } = e.target;
switch (name) {
case "displayname":
setname(value);
break;
case "email":
setemail(value);
break;
default:
break;
}
};
const updateEmailUser = () => {
updateEmail(auth.currentUser, email)
.then(() => {
// Email updated!
// ...
console.log("email Updated");
})
.catch((error) => {
// An error occurred
console.log("email Updated");
// ...
console.log(error);
});
};
const updateUserProfile = () => {
updateProfile(auth.currentUser, {
displayName: name,
})
.then(() => {
console.log("profile Updated" + name + " " + email);
})
.catch((error) => {
console.log(error + "In update profile");
});
updateEmailUser();
};
const handleSubmit = () => {
// updateEmailUser();
updateUserProfile();
signUp(name, userType, email);
let path =
userType === "salonOwner" ? "/addBuisnessDetails" : "/salonsNearby";
if (signupError) {
console.log(signupError.message);
}
return navigate(path, { replace: true });
};
//query function for saloon
return (
<>
<div className="form-wrapper ">
<div id="register-form">
<p className="login-title register-title">Complete Your Profile</p>
<div className="login-hr" />
<form onSubmit={handleSubmit}>
<div className="form-group login-sj">
<label htmlFor="exampleInputName1">Name:</label>
<input
type="text"
className="form-control"
id="exampleInputName1"
aria-describedby="emailHelp"
placeholder="Your Name"
name="displayname"
onChange={handleChange}
/>
</div>
<div className="form-group login-sj">
<label htmlFor="exampleInputEmail2">Email address</label>
<input
type="email"
className="form-control"
id="exampleInputEmail2"
aria-describedby="emailHelp"
placeholder="Enter email"
name="email"
onChange={handleChange}
/>
</div>
{/* <div className="form-group login-sj">
<label htmlFor="exampleInputPassword1"></label>
<input
type="password"
className="form-control"
id="exampleInputPassword2"
placeholder="Password"
value={userPassword}
onChange={(e) => setUserPassword(e.target.value)}
/>
</div> */}
{signupIsPending ? (
<>
<button
type="submit"
className="btn-auth-sj btn btn-primary"
disabled
>
Save Details
</button>
</>
) : (
<>
<button type="submit" className="btn-auth-sj btn btn-primary">
Save Details
</button>
</>
)}
</form>
</div>
</div>
</>
);
};
export default SaveUserDetails;
The part where error is Comming
.catch((error) => {
console.log(error + "In update profile");
});
Due to this my displayName Is not getting saved and after submitting user is getting logged out automatically.
I also asked this question previously and implemented it as answered Is their any function signupwithphonenumber in firebase just like signupwithemailandpassword? (for web) I want to make user register with his creds
Thanks In advance
Okay So the problem got resolved gust by wrapping updateProfile function(one provided by firebase) into
auth.currentUser.reload().then(() => { /* update profile function here */ })
Or In my case :-
const updateUserProfile = () => {
auth.currentUser.reload().then(() => {
updateProfile(auth.currentUser, {
displayName: name,
})
.then(() => {
console.log("profile Updated" + name + " " + email);
})
.catch((error) => {
console.log(error + "In update profile");
});
updateEmailUser();
});
};

Uncaught TypeError: react__WEBPACK_IMPORTED_MODULE_0__.useContext(...) is null when calling set function

I'm trying to set up a user login system using the userContext and localSotrage of the browser.
I have a first file that includes my provider and my context:
Auth.jsx
import { hasAuthenticated } from '../services/AuthAPI';
export const AuthContext = createContext()
const AuthProvider = ({children}) => {
const [auth, setAuth] = useState(hasAuthenticated());
const value = useMemo(() => ({auth, setAuth}, [auth, setAuth]));
return (
<AuthContext.Provider value={value}>{children}</AuthContext.Provider>
)
}
export default AuthProvider
export const AuthState = () => {
return useContext(AuthContext)
}
I also have a page that allows to manage elements of the LocalStorage and to know if a user is already connected (it for now hardcoded):
AuthAPI.jsx
export function hasAuthenticated() {
const token = getItem('sessionToken');
const result = token ? tokenIsValid(token) : false;
if (false === result) {
removeItem('sessionToken');
}
return result;
}
export function login(credentials) {
addItem('sessionToken', 'tokenSample');
return true;
};
export function logout() {
removeItem('sessionToken');
}
function tokenIsValid(token) {
// const { exp: expiration } = jwtDecode(token);
// if (expiration * 1000 > new Date().getTime()) {
// return true;
// }
return true;
}
And finally I have my connection page which must update the auth variable using the context:
Login.jsx
import { useNavigate } from 'react-router-dom';
import { AuthContext } from '../contexts/Auth';
import { login } from '../services/AuthAPI';
const Login = () => {
const navigate = useNavigate();
const {auth, setAuth} = useContext(AuthContext);
const [user, setUser] = useState({
username: "",
password: ""
})
const handleChange = ({ currentTarget }) => {
const { name, value } = currentTarget;
setUser({ ...user, [name]: value })
}
async function handleSubmit(event) {
event.preventDefault();
try {
const response = await login(user);
setAuth(response);
navigate('news', { replace: true });
console.log('oui');
} catch (e) {
console.error(e);
}
}
useEffect(() => {
if (auth) {
navigate('news', { replace: true });
}
}, [navigate, auth]);
return (
<div className="container border rounder mt-5 p-3 bg-light">
<form className="form-profile" onSubmit={setAuth(true)} >
<fieldset>
<legend>Se connecter</legend>
<div className="form-group">
<label htmlFor="email">Email</label>
<input
type="text"
name="username"
className="form-control"
id="email"
placeholder="mail#mail.fr"
onChange={handleChange}
/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input
type="password"
name="password"
className="form-control"
id="password"
placeholder="Password"
onChange={handleChange}
/>
</div>
<button type="submit" className="btn btn-outline-primary">
Se connecter
</button>
</fieldset>
</form>
</div>
);
};
export default Login;
But React returns this error:
Uncaught TypeError: react__WEBPACK_IMPORTED_MODULE_0__.useContext(...) is null site:stackoverflow.com at line setAuth(response); from Login.jsx
Do you have any idea ?

Login page issues while using react js and Django api

I am creating a simple login page using react js and Django api. I am able to login but unable to go to my dashboard as it is throwing error like "Unhandled Rejection (TypeError): Cannot read property 'status' of undefined"
I am using Visual Studio Code
The full code is as below:
Login.js
import React, { useState } from 'react';
import axios from 'axios';
import { setUserSession } from './Utils/Common';
function Login(props) {
const [loading, setLoading] = useState(false);
const username = useFormInput('');
const password = useFormInput('');
const [error, setError] = useState(null);
// handle button click of login form
const handleLogin = () => {
setError(null);
setLoading(true);
axios.post('http://localhost:8000/account/user/signin', { mobile_number: username.value,
password: password.value }).then(response => {
setLoading(false);
setUserSession(response.data.token, response.data.user);
props.history.push('/dashboard');
}).catch(error => {
setLoading(false);
if (error.response.status === undefined) setError(error.response.data.message);
else setError("Something went wrong. Please try again later.");
});
}
return (
<div>
Login<br /><br />
<div>
Username<br />
<input type="text" {...username} autoComplete="new-password" />
</div>
<div style={{ marginTop: 10 }}>
Password<br />
<input type="password" {...password} autoComplete="new-password" />
</div>
{error && <><small style={{ color: 'red' }}>{error}</small><br /></>}<br />
<input type="button" value={loading ? 'Loading...' : 'Login'} onClick={handleLogin}
disabled={loading} /><br />
</div>
);
}
const useFormInput = initialValue => {
const [value, setValue] = useState(initialValue);
const handleChange = e => {
setValue(e.target.value);
}
return {
value,
onChange: handleChange
}
}
export default Login;
Dashboard.js
import React from 'react';
import { getUser, removeUserSession } from './Utils/Common';
function Dashboard(props) {
const user = getUser();
//handle click event of logout button
const handleLogout = () => {
removeUserSession();
props.history.push('/login');
}
return (
<div>
Welcome {user.name}!<br /><br />
<input type="button" onClick={handleLogout} value="Logout" />
</div>
);
}
export default Dashboard;

My course data is not fetching from action to store and after refreshing the page its no longer seen in redux

when i add course i can see that in AllCourses list and in redux but when i refresh the the Allcourse list is empty and redux is empty too i think there is some thing wrong in courses.ja/actions. what am I doing wrong?
courses.js/actions
i think data in not fetching in reducer to store thre is sme thing wrong with the code or something else
import {coursesRef} from '../services/fire';
const FETCH_COURSES = 'FETCH_COURSES';
export const addCourse = newCourse => async dispatch => {
coursesRef.push().set(newCourse);
};
export const removeCourse = removeCourse => async dispatch => {
coursesRef.child(removeCourse).remove();
};
export const fetchCourse = () => async dispatch => {
coursesRef.on("value", snapshot => {
dispatch({
type: FETCH_COURSES,
payload: snapshot.val()
});
});
};
AddCourse.js
import React, { useEffect, useState } from 'react';
import { Button, Form, FormGroup, Label, Input, FormText, Container } from 'reactstrap';
import database from '../services/fire';
import { useSelector, useDispatch } from 'react-redux';
import uuid from 'react-uuid';
import '../App.css';
const AddCourse = () => {
const [courseId, setCourseId] = useState('');
const [courseTitle, setCourseTitle] = useState('');
const [courseDesc, setCourseDesc] = useState('');
const dispatch = useDispatch();
const user = useSelector(state => state.auth.user.uid);
useEffect(() => {
document.title = "Add Courses"
}, [])
const addCourse = () => {
const payload = { id: uuid(), courseId:courseId, courseTitle: courseTitle, courseDesc: courseDesc }
const dbcoursesWrapper = database.ref().child(user).child('courses');
// const dbcoursesWrapper = database.ref(`users/${user}/courses`).push(courseId, courseTitle, setCourseDesc);
return dbcoursesWrapper.child(payload.id).update(payload).then(() => {
setCourseId('');
setCourseTitle('');
setCourseDesc('');
dispatch({ type: "ADD_COURSES", payload });
})
}
return (
<div>
<h1 className="text-center my-3">Fill Course Detail</h1>
<Form onSubmit={(e) => {
e.preventDefault(e.target.value);
addCourse();
}}>
<FormGroup>
<label for="UserId">Course Id</label>
<Input
type="text"
value={courseId}
onChange={(e) => setCourseId(e.target.value)}
placeholder="Enter your Id"
name="userId"
id="UserId"
/>
</FormGroup>
<FormGroup>
<label for="title">Course Title</label>
<Input
type="text"
value={courseTitle}
onChange={(e)=> setCourseTitle(e.target.value)}
placeholder="Enter Course Title"
name="title"
id="title"
/>
</FormGroup>
<label for="description">Course Description</label>
<Input
value={courseDesc}
onChange={(e) => setCourseDesc(e.target.value)}
type="textarea"
placeholder="Enter Course Description"
name="description"
id="description"
style={{ height: 150 }}
/>
<Container className="text-center">
<Button color="success" type='submit'>Add Course</Button>
<Button color="warning ml-3">clear</Button>
</Container>
</Form>
</div>
);
};
export default AddCourse;
AllCourses.js code
onst AllCourses = () => {
const dispatch = useDispatch();
const courses = useSelector(state => state.courses);
const coursesArray = Object.values(courses);
useEffect(()=>{
console.log(coursesArray);
},[])
return (
<div>
<h1>All-Courses</h1>
<p>List Of Couses are as follows</p>
{coursesArray.length}
{ coursesArray.length > 0 ? coursesArray.map((item) =>
<Course course={item} />) : "No Courses"
}
</div>
)
}
export default AllCourses;
you need to call fetchCourse in AllCourses.js
useEffect(() => {
fetchCourse();
}, [])
So whenever you are on all courses component, or you refresh page you will get the courses.
make a
fetchCourse
function in action so can call it in different places for delete course view course etc
action.js
export const fetchCourse = (user) => async dispatch => {
const coursesRef = database.ref().child(user).child('courses');
coursesRef.once('value')
.then((snapshot) => {
const courses = [];
snapshot.forEach((childSnapshot) => {
courses.push({
id: childSnapshot.key,
...childSnapshot.val()
});
});
// dispatch(setcourses(courses));
dispatch({ type: "FETCH_COURSES", courses });
});
};
reducer corses.js
case 'FETCH_COURSES':
return action.courses
allCourses.js
useEffect(()=>{
dispatch(fetchCourse(user));
},[])

_this2.props.signup is not a function in React Redux app

Please note that I've already checked answers in this question and nothing seems to work.
I'm using this repo as a boilerplate. Instead of firebase database, I'm trying to send username and email with the firebase auth userid , to the node server. I created an action creator signup to handle this.
This is signup.js action creator
import * as types from '../constants/action_types';
import axios from 'axios';
export const signup = (user) => {
console.log(user);
return async dispatch => {
try {
const response = await axios.get('http://localhost:5000/api/user/register', user)
const data = await {response};
dispatch({
type : types.SIGN_UP,
payload : data.fromback
})
} catch (error) {
console.lot(error)
}
}
}
Then I've connected it with the component with mapDispatchToProps., So,under the SignUpPage component, React dev tools shows signup as a function. But when it get triggers, it gives an error saying _this2.props.signup is not a function Why's that ?
This is my SignUpPage component
import React, { Component } from 'react';
import {
Link,
withRouter,
} from 'react-router-dom';
import { auth } from '../../firebase';
import * as routes from '../../constants/routes';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import {signup} from './../../actions/signup';
const SignUpPage = ({ history }) =>
<div>
<h1>SignUp</h1>
<SignUpForm history={history} />
</div>
const updateByPropertyName = (propertyName, value) => () => ({
[propertyName]: value,
});
const INITIAL_STATE = {
username: '',
email: '',
passwordOne: '',
passwordTwo: '',
error: null,
};
class SignUpForm extends Component {
constructor(props) {
super(props);
this.state = { ...INITIAL_STATE };
}
onSubmit = (event) => {
const {
username,
email,
passwordOne,
} = this.state;
const {
history,
} = this.props;
auth.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
const userid = authUser.user.uid;
const user = { email, userid };
this.props.signup(user);
})
.catch(error => {
this.setState(updateByPropertyName('error', error));
});
event.preventDefault();
}
render() {
const {
username,
email,
passwordOne,
passwordTwo,
error,
} = this.state;
const isInvalid =
passwordOne !== passwordTwo ||
passwordOne === '' ||
username === '' ||
email === '';
return (
<form onSubmit={this.onSubmit}>
<input
value={username}
onChange={event => this.setState(updateByPropertyName('username', event.target.value))}
type="text"
placeholder="Full Name"
/>
<input
value={email}
onChange={event => this.setState(updateByPropertyName('email', event.target.value))}
type="text"
placeholder="Email Address"
/>
<input
value={passwordOne}
onChange={event => this.setState(updateByPropertyName('passwordOne', event.target.value))}
type="password"
placeholder="Password"
/>
<input
value={passwordTwo}
onChange={event => this.setState(updateByPropertyName('passwordTwo', event.target.value))}
type="password"
placeholder="Confirm Password"
/>
<button disabled={isInvalid} type="submit">
Sign Up
</button>
{ error && <p>{error.message}</p> }
</form>
);
}
}
const SignUpLink = () =>
<p>
Don't have an account?
{' '}
<Link to={routes.SIGN_UP}>Sign Up</Link>
</p>
const mapDispatchToProps = dispatch => bindActionCreators({ signup }, dispatch)
export default connect(null, mapDispatchToProps)(withRouter(SignUpPage));
export {
SignUpForm,
SignUpLink,
};
Its not a prop,
you've imported it as a function,
you can directly use it as function like this
import {signup} from './../../actions/signup';
.....
auth.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
const userid = authUser.user.uid;
const user = { email, userid };
signup(user);
})
.catch(error => {
this.setState(updateByPropertyName('error', error));
});

Categories

Resources