Page refreshing when registering new user in firebase - javascript

I am developing a firebase website, and when I try to register an account, the page refreshes. The function is called in the onsubmit method of a form.
<form id="register_form" onsubmit="registerNewUser(); return false;">
I put return false, but it keeps on refreshing the page. I did more debugging, and found out it is not when the form is submitted, but rather when creating the new user. Here is my user registration code.
function registerNewUser() { firebase.auth().createUserWithEmailAndPassword($("#register_email").val, $("#register_password").val)
.then((user) => {
// Signed in
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
window.alert(errorMessage);
// ..
});
}
What am I doing wrong?

Related

Firebase signInWithEmailAndPassword and onAuthStateChanged Realtime Database logging issue

I'm working on a webpage using HTML5 CCS etc, where it uses a authentication process using firebase for users. Its my first time ever working on firebase, so i still have no idea how to correctly code using it.
I manually add a admin user on firebase, so i can use those credentials to log in to the webpage. In the signInWithEmailAndPassword i used a code to log into the console some information about credentials, but whats happening is that while it does work (the authentication). The only way it logs info into the console is when i don't redirect the user to another page using the onAuthStateChanged (basically not using it at all).
Basically it authenticates correctly, but its doesn't log the info in the realtime database unless i remove the onAuthStateChanged.
Here is the code
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
const dt = new Date();
update(ref(database, 'users/' + user.uid), {
Email: email,
Password: password,
Last_Login: dt
})
alert('Usuario ingresado!')
location.href = 'test.html'
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
alert(errorMessage)
});
});
const user = auth.currentUser;
onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
location.href = 'test.html'
// ...
} else {
// User is signed out
// ...
}
});
I heard this process is asynchronous.
Calls to Firebase (and most modern cloud APIs) are asynchronous, since they may take some time to complete. But as soon as the user is signed in, the local onAuthStateChanged will be called - which interrupts the write to the database.
If the user always actively signs in to this page (so you always call signIn...), then you don't need the onAuthStateChanged handler and can just include the navigation code in the then:
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
const dt = new Date();
update(ref(database, 'users/' + user.uid), {
Email: email,
Password: password,
Last_Login: dt
}).then(() => {
location.href = 'test.html'; // πŸ‘ˆ
})
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
alert(errorMessage)
});
});

FireBase user authentication redirect to another page

I have created a signupPage.html to authenticate a user and and log information to the realtime database in firebase using this code:
signUp_button.addEventListener('click', (e) => {
var email = document.getElementById('email').value;
var password = document.getElementById('password').value;
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
//signed up
const user = userCredential.user;
//log to database
set(ref(database, 'users/' + user.uid),{
email : email
})
//this is where page redirection
alert('User Created');
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
alert(errorMessage);
});
});
Then when I click my submit button everything works and the user is authenticated and information is stored into the realtime database. Now I want to redirect the user to a login page after they submit their signup. In my code under "this is where page redirection", I put location.href = "login.html". This does redirect the page and authenticate the user but it no longer stores the data into the realtime database. Any suggestions?
You were close. set() is an asynchronous action, so by adding the redirect where you were, you would redirect before the set() had the chance to execute. You must first wait for the set() to finish, and then redirect.
signUp_button.addEventListener('click', (e) => {
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
createUserWithEmailAndPassword(auth, email, password)
.then(async (userCredential) => {
//signed up
const user = userCredential.user;
// log to database & wait for it to finish!
return set(ref(database, 'users/' + user.uid), {
email : email
})
})
.then(() => {
alert('User Created'); // avoid alert, it blocks user input!
// update a div with an information message instead
location.href = "login.html";
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
alert(errorMessage); // avoid alert, it blocks user input!
// update a div with an error message instead
});
});

Firebase onAuthStateChanged() triggering before retrieving name from signup form?

I'm creating a dashboard using vanilla HTML, CSS and JS, with Firebase as my backend. In my signup.html page, I have a form that allows users to input their name along with their email address and password. Upon signup, users are redirected to dashboard.html with their personalized content. Inside the dashboard, it has a spot where it displays their name.
The problem is it is not always getting the name from the form, and if it doesn't get the user's name from the signup form then it just doesn't have their name as I don't have a "add name" function in the dashboard. I suspect this is because of the way I use the onAuthStateChanged() inside signup.html.
The following is my signup page JS code:
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
window.location.replace('dashboard.html')
} else {
return
}
});
document.querySelector('#signup_btn').addEventListener("click", (e) => {
e.preventDefault();
var user_email = document.getElementById('user_email').value;
var user_pass = document.getElementById('user_pass').value;
var user_name = document.getElementById('user_name').value;
// Sign Up
firebase.auth().createUserWithEmailAndPassword(user_email, user_pass)
// Success
.then((userCredentials) => {
userCredentials.user.updateProfile({
displayName: user_name
})
})
// Errors
.catch(function (error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode == 'auth/weak-password') {
alert('The password is too weak.');
} else {
alert(errorMessage);
}
console.log(error);
});
})
If it helps, here is the form from my signup.html page:
<form>
<h1>Sign Up</h1>
<!-- <h2>Log into your account using your email address</h2> -->
<label for="user_name">Name</label>
<input type="text" name="name" id="user_name">
<label for="user_email">Email Address</label>
<input type="text" name="email" id="user_email">
<label for="user_pass">Password</label>
<input type="password" name="Password" id="user_pass">
<button type="submit" id="signup_btn">Sign Up</button>
<p>Already have an account? Log In</p>
</form>
It seems like your onAuthStateChanged listener is being triggered before the write to the database has completed. This is the expected behavior for the API, but not what you want here.
Since you do want to use the onAuthStateChanged listener to navigate on page reload, the best I can think off is to turn off the listener when the user clicks the sign up button:
// πŸ‘‡ store the unsubscribe function in a variable
var unsubscribe = firebase.auth().onAuthStateChanged(function (user) {
if (user) {
window.location.replace('dashboard.html')
} else {
return
}
});
document.querySelector('#signup_btn').addEventListener("click", (e) => {
e.preventDefault();
unsubscribe(); // πŸ‘ˆ turn off auth state listener
var user_email = document.getElementById('user_email').value;
var user_pass = document.getElementById('user_pass').value;
var user_name = document.getElementById('user_name').value;
// Sign Up
firebase.auth().createUserWithEmailAndPassword(user_email, user_pass)
// Success
.then((userCredentials) => {
return userCredentials.user.updateProfile({ // πŸ‘ˆ add a return
displayName: user_name
})
})
.then(() => {
window.location.replace('dashboard.html') // πŸ‘ˆ explicitly navigate here
})
As mentioned in the documentation,
onAuthStateChanged adds an observer for changes to the user's sign-in state.
When the user is logged in, it redirects your user to /dashboard before the updateProfile is resolved resulting in termination of that request.
I don't think you'll need an auth state listener on login page so try refactoring the code like this:
window.onload = function () {
if (firebase.auth().currentUser) window.location.replace("dashboard.html")
// Else stay on this page
// button click events here
}

Javascript and Firebase - Create user with Email and password and onAuthStateChange

Hi I'm having problems finding a way to have an auth state change auto direct to a page for logged in users. Before a user is created however I want to push to my database a user Profile.
So I create the user then add to the database with this code
firebase.auth().createUserWithEmailAndPassword(email, password).then(function (user){
firebase.database().ref('/Profiles').child(user.uid).set({
address: ''
})
}).catch(function(error){
let errorCode = error.code;
let errorMessage = error.message;
navigator.notification.alert('Error: Code: ' + errorCode + ', ' + errorMessage,false,'Error','Done');
});
However, Once the createUserWithEmailAndPassword is successful This onAuthStateChanged function navigates to the new page before the database 'Profile' record is added.
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
let u = firebase.auth().currentUser;
window.location = 'loggedIn.html';
}
});
How can I make it so that my onAuthStateChanged function waits for the database record to be added before navigating away from the page
NOTE:: I want to keep the onAuthStateChanged so that if a user is logged into the session they will auto directed to the loggedIn page
You can try to register the onAuthStateChagned handler after saving to database.
I had the same problem. I tried several stuffs but one simple setState for some reason solved this issue.
Try to setState for something inside the createUserWithEmailAndPassword function. For example:
firebase.auth().createUserWithEmailAndPassword(email, password).then(function (user){
firebase.database().ref('/Profiles').child(user.uid).set({
address: ''
})
// SET Some state
this.setState({ error: null, isLoading: false });
// Besides that I show the feedback as an alert (just in case you think it's a good idea)
Alert.alert(
`Welcome ${user.user.name}!`,
'Your account has been successfully created.',
[
{
text: 'OK',
onPress: () =>
navigation.navigate('Main'),
},
]
);
}).catch(function(error){
let errorCode = error.code;
let errorMessage = error.message;
navigator.notification.alert('Error: Code: ' + errorCode + ', ' + errorMessage,false,'Error','Done');
});

"auth/user-not-found" when signing in user with Firebase

I have a firebase app connected to monaca CLI and OnsenUI. I am trying to create a user and log them in in the same action. I can successfully create a user, but I can't log in. When I log them in I get the following error
auth/user-not-found
and
There is no user record corresponding to this identifier. The User may have been deleted
I confirmed that the new user is in the db...Here is my code for the signup and signin
//signup function stuff
var login = function() {
console.log('got to login stuff');
var email = document.getElementById('username').value;
var password = document.getElementById('password').value;
//firebases authentication code
firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
console.log('User did not sign up correctly');
console.log(errorCode);
console.console.log(errorMessage);
});
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
console.log(error.code);
console.log(error.message);
});
fn.load('home.html');
};
You have a so-called race condition in your flow.
When you call createUserWithEmailAndPassword() Firebase starts creating the user account. But this may take some time, so the code in your browser continues executing.
It immediately continues with signInWithEmailAndPassword(). Since Firebase is likely still creating the user account, this call will fail.
The solution in general with this type of situation is to chain the calls together, for example with a then():
firebase.auth().createUserWithEmailAndPassword(email, password).then(function(user) {
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
console.log(error.code);
console.log(error.message);
});
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
console.log('User did not sign up correctly');
console.log(errorCode);
console.console.log(errorMessage);
});
But as AndrΓ© Kool already commented: creating a user automatically signs them in already, so in this case you can just do:
firebase.auth().createUserWithEmailAndPassword(email, password).then(function(user) {
// User is created and signed in, do whatever is needed
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
console.log('User did not sign up correctly');
console.log(errorCode);
console.console.log(errorMessage);
});
You'll likely soon also want to detect whether the user is already signed in when they get to your page. For that you'd use onAuthStateChanged. From the docs:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
async/await works too.
(async () => {
try {
const result = await auth().createUserWithEmailAndPassword(email, password).signInWithEmailAndPassword(email, password);
console.log(result);
} catch (error) {
console.error(error);
}
})()

Categories

Resources