After logging in, the page to which the user is redirected is refreshing repeatedly.
Here is the javascript code:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
window.location="comingsoon.html";
var user = firebase.auth().currentUser;
} else {
// No user is signed in.
}
});
function login(){
var userEmail = document.getElementById("email_field").value;
var userPass = document.getElementById("password_field").value;
firebase.auth().signInWithEmailAndPassword(userEmail, userPass).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
window.alert("Error : " + errorMessage);
// ...
});
}
function logout(){
firebase.auth().signOut();
}
You have to unsubscribe from the event listening function onAuthStateChanged after you execute your code. To do this you can write :
const unsubscribeAfterAuth = firebase.auth().onAuthStateChanged(function (user) {
if (user) {
window.location="comingsoon.html";
var user = firebase.auth().currentUser;
} else {
// No user is signed in.
}
});
unsubscribeAfterAuth();
This way you won't get updates after the first onAuthStateChanged as your function won't be listening to the event after the first call.
Related
I found a tutorial on how to save the user's data under the uid in firestore. My function successfully retrieves the data and authenticates it, but it skips the firestore save function and jumps to the next window. I have two questions, why is it skipping the store in firebase function and why isn't reading the newly authenticated user as the current user when I set it and go to the next window? Sorry for all the similar questions, I'm trying different ways to do this and none have worked for me so far. I have provided my code below.
JS:
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// Initialize variables
const auth = firebase.auth();
const db = firebase.firestore().collection("/studiopick/studios/users");
const element = document.querySelector("form");
element.addEventListener("submit", (event) => {
event.preventDefault();
// renamed from newStudio
// don't use alert - it blocks the thread
console.log("debug: retrieving data... please wait");
// Get data
(studioName = document.getElementById("studioName").value),
(email = document.getElementById("email").value),
(password = document.getElementById("password").value),
(firstName = document.getElementById("firstName").value),
(lastName = document.getElementById("lastName").value),
(phoneNumber = document.getElementById("phoneNumber").value);
console.log({ studioName, firstName, email }); // note added braces here
// Validate input fields
if (!validate_email(email) || !validate_password(password)) {
// TODO: replace this alert with updating the form with an error message
alert("Error with email or password");
return false; // cancel submission
}
if (
!validate_field(firstName) ||
!validate_field(lastName) ||
!validate_field(phoneNumber) ||
!validate_field(studioName)
) {
// TODO: replace this alert with updating the form with an error message
alert("One or More Extra Fields is Outta Line!!");
return false; // cancel submission
}
console.log("Info grab successful");
// creates the user, and waits for it to finish being created
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then(function (userCredential) {
usersRef.doc(`${userCredential.user.uid}`).set({
studioName: studioName,
firstName: firstName,
lastName: lastName,
email: email,
phoneNumber: phoneNumber,
uid: userCredential.user.uid,
});
})
.catch(function (error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// [START_EXCLUDE]
if (errorCode == "auth/weak-password") {
alert("The password is too weak.");
} else {
alert(errorMessage);
}
console.log(error);
// [END_EXCLUDE]
});
const uid = firebase.auth().currentUser;
// once the above tasks succeed, navigate to the dashboard.
window.location.href = "studiodash.html?id=" + uid;
return false;
});
// Validate Functions
function validate_email(email) {
expression = /^[^#]+#\w+(\.\w+)+\w$/;
if (expression.test(email) == true) {
// Email is good
return true;
} else {
// Email is not good
return false;
}
}
function validate_password(password) {
// Firebase only accepts lengths greater than 6
if (password < 6) {
return false;
} else {
return true;
}
}
function validate_field(field) {
if (field == null) {
return false;
}
if (field.length <= 0) {
return false;
} else {
return true;
}
}
Ended up figuring it out myself. Hope this helps someone:
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
console.log("firebase ===", firebase);
// Initialize variables
const auth = firebase.auth();
const db = firebase.firestore().collection("/studiopick/studios/users");
const element = document.querySelector("form");
element.addEventListener("submit", (event) => {
event.preventDefault();
// renamed from newStudio
// don't use alert - it blocks the thread
console.log("debug: retrieving data... please wait");
// Get data
(studioName = document.getElementById("studioName").value),
(email = document.getElementById("email").value),
(password = document.getElementById("password").value),
(firstName = document.getElementById("firstName").value),
(lastName = document.getElementById("lastName").value),
(phoneNumber = document.getElementById("phoneNumber").value);
console.log({ studioName, firstName, email }); // note added braces here
// Validate input fields
if (!validate_email(email) || !validate_password(password)) {
// TODO: replace this alert with updating the form with an error message
alert("Error with email or password");
return false; // cancel submission
}
if (
!validate_field(firstName) ||
!validate_field(lastName) ||
!validate_field(phoneNumber) ||
!validate_field(studioName)
) {
// TODO: replace this alert with updating the form with an error message
alert("One or More Extra Fields is Outta Line!!");
return false; // cancel submission
}
console.log("Info grab successful");
// creates the user, and waits for it to finish being created
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then(async (userCredential) => {
console.log("userCredential ===", userCredential);
var usersRef = db;
await usersRef.doc(`${userCredential.user.uid}`).set({
studioName: studioName,
firstName: firstName,
lastName: lastName,
email: email,
phoneNumber: phoneNumber,
uid: userCredential.user.uid,
});
console.log("firebase.auth().currentUser ===", firebase.auth().currentUser.uid);
const uid = firebase.auth().currentUser.uid;
// once the above tasks succeed, navigate to the dashboard.
window.location.href = "studiodash.html?id=" + uid;
})
.catch((error) => {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// [START_EXCLUDE]
if (errorCode == "auth/weak-password") {
alert("The password is too weak.");
} else {
alert(errorMessage);
}
console.log(error);
// [END_EXCLUDE]
});
return false;
});
// Validate Functions
function validate_email(email) {
expression = /^[^#]+#\w+(\.\w+)+\w$/;
if (expression.test(email) == true) {
// Email is good
return true;
} else {
// Email is not good
return false;
}
}
function validate_password(password) {
// Firebase only accepts lengths greater than 6
if (password < 6) {
return false;
} else {
return true;
}
}
function validate_field(field) {
if (field == null) {
return false;
}
if (field.length <= 0) {
return false;
} else {
return true;
}
}
I am trying to update my firebase realtime database with user info when I am creating new user through firebase password authentication. And on successful sign in I am moving to another page. The problem is that my database is not getting updated in the above scenario however if stay in the login page and don't change to any other url; the database gets updated.
Here's my create user code
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((userCredential) => {
// Signed in
var user = userCredential.user;
if (user !== null) {
const db = firebase.database();
db.ref("/").set({
uid: user.uid,
});
}
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorCode, errorMessage);
// ..
});
And here's where I'm switching to another page,
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
var uid = user.uid;
console.log(user);
//If I remove the below line, database is updated
window.location.href = "../html/home.html";
// ...
} else {
// User is signed out
// ...
console.log("not logged in");
}
});
This calls is asynchronous:
db.ref("/").set({
uid: user.uid,
});
That means that the code continues to run after the set() function returns, and asynchronously sends the data to the database. But when you change window.location, it interrupts this write operation. That's also why it works when you don't send the user to a new location: the write operation can then complete without interruption.
A quick simple fix is to flag when you're updating the database:
isCreatingUser = true; // 👈 Flag that we're creating a user
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((userCredential) => {
var user = userCredential.user;
if (user !== null) {
const db = firebase.database();
db.ref("/").set({
uid: user.uid,
}).then(() => {
isCreatingUser = false; // 👈 We're done
window.location.href = "../html/home.html"; // 👈 Navigate away
}).catch((e) => {
isCreatingUser = false; // 👈 We're done
throw e;
})
}
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorCode, errorMessage);
// ..
isCreatingUser = false; // 👈 We're done
});
And then:
firebase.auth().onAuthStateChanged((user) => {
if (user && !isCreatingUser) {
...
You'll probably need some more synchronization, but that's the gist of it.
It always gives me "first argument (email) must be a valid string" and it doesn't login
i don't know if the problem is in the js code but im pretty sure it's not in the html .
and another question .. do i need the " onAuthStateChanged " function?
<script>
var rightAccount = 0;
var email = $("#inputEmail").val();
var password = $("#inputPassword").val();
SignIn();
function SignIn(email,password) {
firebase.auth().signInWithEmailAndPassword(email, password)
.then((user) => {
authStateListener();
rightAccount = 1;
//Signed in
// ...
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorMessage);
alert(errorMessage);
});
};
function authStateListener() {
// [START auth_state_listener]
firebase.auth().onAuthStateChanged((user) => {
if (user) {
var uid = user.uid;
currentUser = user;
console.log(currentUser.email + " has logged in")
} else {
// ...
}
});
// [END auth_state_listener]
};
if (rightAccount == 1) {
setTimeout(function Redirect() {
window.location.replace("Website/homePage.php");
}, 2000)
}
</script>
You must pass email and password values to function. Otherwise it will be give error.
...
var email = $("#inputEmail").val();
var password = $("#inputPassword").val();
SignIn(email, password); // <-- Here pass them
...
My login function works fine but after logging out it redirects me back to my login landing page. The AuthState in the login js doesnt change is it a bug or do i have an error in my code.
Login.js
function loginBtn(){
var userEmail = document.getElementById("email_field").value;
var userPass = document.getElementById("password_field").value;
firebase.auth().signInWithEmailAndPassword(userEmail,userPass).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
console.log(error.Message);
window.alert("Error : " + errorMessage);
});
}
firebase.auth().onAuthStateChanged(user => {
if(user) {
window.location = '/home';
}
});
function recaptchaCallback() {
$('#submitBtn').removeAttr('disabled');
};
Auth.js
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
} else {
// No user is signed in.
firebase.auth().signOut();
alert('NOT LOGGED IN');
window.location='/';
}
});
function logout(){
firebase.auth().signOut();
alert('SIGNED OUT');
window.location='/';
}
I solved it by placing the OnAuthStateChanged to document ready since the listener is too slow to load.
$(document).ready(function(){
firebase.auth().onAuthStateChanged(user => {
if(user) {
window.location = '/home';
}
});
});
I'm trying to add a login with social media on my website, but I got some errors because the case is returning first before my HTTP request (Firebase):
firebase.auth().signInWithPopup
How can I use the async function in some way to the case await until the request is complete?
Here is the code:
login(provider, info) {
switch (provider) {
case this.EMAIL:
return firebaseAuth().signInWithEmailAndPassword(
info.email,
info.password
);
break;
case this.EMAILREGISTER:
break;
case this.GOOGLE:
var providerr = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(providerr).then(function(result) {
// This gives you a Facebook Access Token. You can use it to access the Facebook API.
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
console.log(result);
// ...
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
console.log(error);
// ...
});
//Right here I need to return the token and user async
break;
}
}
//here is the function who is calling:
handleLogin = () => {
const { email, password } = this.state;
if (!(email && password)) {
notification('error', 'Favor informar o email e senha');
return;
}
this.setState({
confirmLoading: true
});
const self = this;
let isError = false;
Firebase.login(Firebase.Google, '')
.catch(result => {
const message =
......
});
}
You can try using async/await so that it will wait till the data is returned. Something like this, just to get you started:
async login(provider, info) {
try {
switch (provider) {
case this.EMAIL:
return firebaseAuth().signInWithEmailAndPassword(
info.email,
info.password
);
break;
case this.EMAILREGISTER:
break;
case this.GOOGLE:
var providerr = new firebase.auth.GoogleAuthProvider();
// This gives you a Facebook Access Token. You can use it to access the Facebook API.
var result = await firebase.auth().signInWithPopup(providerr);
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
console.log(result);
// ...
break;
}
}
catch(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
console.log(error);
// ...
}
}
}