I use the next for the login of my application. When you successfuly login you're redirected to a dashboard with a Form.
async function loginUser(e) {
e.preventDefault()
await Axios.post("http://localhost:3005/users/login", {
email,
password
}).then((response) => {
if (!response.data.auth){
setSession(null)
} else{
setSession(response.data.token, response.data.user)
}
});
};
export const getUser = () =>{
const user = sessionStorage.getItem("user");
if(user) return JSON.parse(user);
else return null;
}
export const getToken = () => {
return sessionStorage.getItem("token") || null
}
export const setSession = (token, user) => {
sessionStorage.setItem("token", token)
sessionStorage.setItem("user", JSON.stringify(user))
}
export const removeSession = () => {
sessionStorage.removeItem("token")
sessionStorage.removeItem("user")
}
In that dashboard the user can fill the next form. This works good, the forms are posted and the user get to see all the forms that he posted.
I want the user to be able to share the form link with his id embedded to it so whenever someone fill the form you can associate it with the user who shared it.
My problem is that whenever someone tries to fill the form it wont post as the person isnt logged in and form cant get an user id, and even if the person was logged it would pass his id and not the one of the person who shared the form.
const Form = () => {
const user = getUser();
const [firstName, setFirstName] = useState();
const [middleName, setMiddleName] = useState();
const [surname, setSurname] = useState();
const [secondSurname, setSecondSurname] = useState();
const [email, setEmail] = useState();
const [contactNumber, setContactNumber] = useState();
const createForm = () => {
Axios.post("http://localhost:3005/forms", {
firstName,
middleName,
surname,
secondSurname,
email,
contactNumber,
ownerUser: user._id
}).then((response) => {
alert("Form sent");
});
};`
Any help on how to embed the user._id is deeply thanked!
Yeah, I wouldn't think there's a way to embed it just sharing the form's link with no further reference. You could generate some sort of other usable ID that you can add to the specific form's URL, if you don't want to use the user's ID directly. And associate that one to the user ID in the back-end. Then finally grab it through the form's page through dynamic variable.
Example:
website.com/form/:id
And using props.match.params.id with Router, or your decided strategy.
Edits: Minor wording
Okay so here is what I did, i created 2 components; one form for the logged user he can fill it normally and it has a button that redirect to a form that is intendeed to be shared:
So logged user form looks like this:
const Form = () => {
const user = getUser();
const own = user._id;
const navigate = useNavigate();
const nav = (own) => {
navigate(`/form/${own}`)
}
/// states, axios and the form
<button onClick={createForm}>Send</button>
<button onClick={() => nav(own)} >Go to</button>
Then in the form to be shared I used useMatch from react router dom in the next way to retrieve the user id:
import { useMatch } from "react-router-dom";
const SharedForm = () => {
const params = useMatch(`/form/:own`)
/// console.dir(params)
const owner = params.params.own
On this way the logged user id is embedded to the form and anyone with the link can fill it.
Related
I have multiple users in my app, and I can login smoothly but when I logout and I login as second user I still can see the first user screens until I refresh my app then I can see the second user screen?
Here is my code:
const UserInbox = () => {
const [userData, setUserData] = useState([])
const message = db.collection('feedback').where('recipient','==',userData ?
auth.currentUser.email:'unknown')
{/*fetch only logged in user messages from database*/}
const fetchData = async()=>{
const unsubscribe = auth.onAuthStateChanged(async user => {
const list = [];
if(user){
await message
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
const {userId,recipient,messageText} = doc.data()
list.push({
id:doc.id,
userId,
recipient,
messageText
})
// doc.data() is never undefined for query doc snapshots
console.log(doc.data().messageText);
});
setUserData(list)
})
} else{
setUserData(null)
}
})
return () => unsubscribe();
}
I was trying to fix it but I couldn't figure it out because when I look at my code I don't see any errors but I feel I'm missing something? so please do anyone can help me out to display the right screen for the right logged in without refreshing the app with every single login.
I am creating a frontend dummy e-commerce app. I have created a login page, and the idea is to link the JSON database of users which all have a unique username, password and ID and when you try to login with the parameters you get the Login successful message if there is a user with those parameters in the JSON, and if there is not you get the Fail message. Below is my source code for the login page. For now I have just made a simple if user = user#gmail.com and password = user password, then you get the success message, but the idea is to use the database for multiple user options. The JSON file will be a basic array of user objects.
P.S. stack overflow wont let me post the code unless I put constant and be grammatically correct so I had to separate the use State use navigate and so on
const Login = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [valid, setValid] = useState(false)
const [success, setSuccess] = useState(false)
const navigate = useNavigate()
const handle Submit = (e) => {
if (email === 'user#gmail.com' && password === 'user password') {
setValid(true)
setSuccess(true)
setTimeout(() => {
navigate('/')
},3000)
}
e.preventDefault()
}
}
I will imagine your users array is like so per your description
const users = [
{ id: 1, name: 'John',email: 'user1#gmail.com', password: '123456' },
{ id: 2, name: 'Pete' , email: 'user2#gmail.com', password: '123456' },
{ id: 3, name: 'Mary' , email: 'user3#gmail.com', password: '123456' },
];
your submit function will be like so
const handleSubmit = (e) => {
e.preventDefault();
const user = users.find((user) => user.email === email && user.password === password);
if (user) {
// login success
}
else {
// login failed
}
}
this will check if the user info exists in your JSON data or not
you can replace the login success comment and failure wth your specific logic
You can install the package json-server https://github.com/typicode/json-server or maybe another package that does the same thing.
So ,I am an newbie in firebase and working on an team project. What client wants us to do is make user login with phonenumber and otp.
First, I managed to login the user using this code as follows
import React, { useState } from "react";
import { RecaptchaVerifier, signInWithPhoneNumber } from "firebase/auth";
import { auth } from "../../firebase/config";
const SignInWithNumber = () => {
const [phone, setphone] = useState();
const [otp, setotp] = useState();
const handleRecaptcha = () => {
window.recaptchaVerifier = new RecaptchaVerifier(
"sign-in-button",
{
size: "invisible",
callback: (response) => {
// reCAPTCHA solved, allow signInWithPhoneNumber.
},
},
auth
);
};
const handleSubmitNumber = (e) => {
e.preventDefault();
if (phone >= 10) {
console.log(phone);
handleRecaptcha();
const phoneNumber = "+91" + phone;
const appVerifier = window.recaptchaVerifier;
signInWithPhoneNumber(auth, phoneNumber, appVerifier)
.then((confirmationResult) => {
window.confirmationResult = confirmationResult;
// ...
console.log("otp sent");
})
.catch((error) => {
// Error; SMS not sent
// ...
console.log(error + "SMS not sent");
});
}
};
const handleSubmitOtp = (e) => {
e.preventDefault();
const code = otp;
const x = window.confirmationResult;
x.confirm(code)
.then((result) => {
// User signed in successfully.
const user = result.user;
console.log(user);
// ...
})
.catch((error) => {
// User couldn't sign in (bad verification code?)
// ...
console.log(error);
});
};
const handleChange = (e) => {
e.preventDefault();
const { name, value } = e.target;
switch (name) {
case "phone":
setphone(value);
break;
case "otp":
setotp(value);
break;
default:
break;
}
};
return (
<div>
<h2>LogIn</h2>
<form onSubmit={handleSubmitNumber}>
<div id="sign-in-button"></div>
<input type="number" name="phone" required onChange={handleChange} />
<button type="submit">Submit</button>
</form>
<h2>Submit OTP</h2>
<form onSubmit={handleSubmitOtp}>
<input type="number" name="otp" required onChange={handleChange} />
<button type="submit">Submit</button>
</form>
</div>
);
};
export default SignInWithNumber;
Now , I am able to login user and get its uid in console but I also want to signup/register the user with his phone number +otp and get his credentials such as name , address etc.
This may be a dumb question but I cant find any solution to this.
Thanks in advance :)
There isn't any sign up method when using phone based auth. If a user doesn't exists then the account will be created (technically a sign up) else user will be logged in to existing account.
You can however check the isNewUser property after authentication to check if user logged in for first time or no.
Checkout Check for isNewUser with Firebase email link auth using modular JS SDK
x.confirm(code)
.then((result) => {
// User signed in successfully.
const { isNewUser } = getAdditionalUserInfo(result)
if (isNewUser) {
// New user - sign up
} else {
// Existing user - log in
}
})
First, the question is not dumb.
Secondly, for a solution, after signing in with phone number successfully, given that the account was just created (a new user), you can now show a form to obtain the user's name and other details.
On submit of this form, save the name to firebase authentication user object with updateProfile. Then save other data to a Firestore document with the user's uid as document id and preferably on the users collection.
On page load, you can check if the user is signed in, if true, check if the user has data in Firestore, if false, show the user the above form, else, continue app usage as you want.
I want to add the username on the signup of the user and I am using the following code:
//Create Account With Email&Password
const createUser = (email, password, username) => {
return createUserWithEmailAndPassword(auth, email, password).then(() => {
updateProfile(auth.currentUser, {
displayName: username,
});
});
};
This is my useEffect in the same js file
useEffect(() => {
console.log('useEffect');
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
setUser(currentUser);
});
return () => unsubscribe();
}, []);
This code is adding the displayname successfully, but when I redirect to my account page the displayname is not directly showing up and I am getting a memory leak warning from the router-dom. Is there a cleaner and better way to do this?
I believe it's because the account page loads before firebase loads the auth data, you can use something like
onAuthStateChanged(auth,(user)=>{
if(user){
getUserName = auth.currentUser.displayName;
// Load the rest of the page
}
}
at your redirected user page,assuming you are using the right auth state, which you can refer from here https://firebase.google.com/docs/auth/web/auth-state-persistence?authuser=0
I have the user inside localstorage, when user logouts the localstorage data becomes NULL. When user logins, the localstorages fills with user's data but to check this my userEffect in App.js do not reflect any change.
i have signUp
dispatch(signin(form, history));
history.push("/"); //go back to App.js file
in Navbar the user data changes
const Navbar = (props) => {
const [user, setUser] = useState(JSON.parse(localStorage.getItem("profile")));
const logout = () => {
dispatch({ type: "LOGOUT" });
dispatch({
type: "EMPTY_CART",
});
history.push("/");
setUser(null);
};
now at App.js i have
const user = JSON.parse(localStorage?.getItem("profile"));
const getCartItems = useCallback(async () => {
if (user) {
console.log("Yes user exixts");
dispatch(getEachUserCart(user?.result?._id));
} else {
console.log("No user exist");
}
}, []); //
useEffect(() => {
getCartItems();
}, [getCartItems]);
Now if u look above, after dispatching signUp action, i come back to App.js but here the useEffect don't run nor it checks if user have changed.
Hey – looks like you have a missing dependency issue. You need to have it like so
const getCartItems = useCallback(async () => {
if (user) {
console.log("Yes user exixts");
dispatch(getEachUserCart(user?.result?._id));
} else {
console.log("No user exist");
}
}, [user]);
Otherwise, this function will never be redeclared with the latest user value. Kindly let me know if that helps