This is my used code:
var cred = firebase.auth().EmailAuthProvider($scope.data.mail, $scope.data.pwd);
firebase.auth().signInWithCredential(cred)
.then(function()
During testing, I get the following error:
TypeError: undefined is not a function (evaluating
'firebase.auth().EmailAuthProvider($scope.data.mail,
$scope.data.pwd)')
So what's wrong with my code? How can I fix this problem?
To log a user in via email/pass you just call the signInWithEmailAndPassword method.
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
Then you can listen for the realtime auth event:
firebase.auth().onAuthStateChanged(function(user) {
if (user !== null) {
console.log('logged in!');
}
});
Check the docs here for more on email login.
Check the API reference for onAuthStateChanged for more info.
Fixed By:
const register = () => {
createUserWithEmailAndPassword(auth, email, password)
.then((auth) => {
setPass(1);
})
.catch((error) => alert(error.message));
};
console.log(pass);
if (pass === 1) {
updateProfile(auth.currentUser, {
displayName: name,
photoURL: image || "https://example.com/jane-q-user/profile.jpg",
})
.then(() => {
// Profile updated!
// ...
})
.catch((error) => {
// An error occurred
// ...
});
setPass(0);
}
Related
please help.
I'm trying to ensure that the user does not log out after reloading the page.
const signUp = async (loginEmail, loginPassword) => {
const auth = getAuth()
setPersistence(auth, browserSessionPersistence)
.then(({ user }) => {
dispatch(
setUser({
email: user.email,
id: user.uid,
token: user.accessToken,
})
)
return signInWithEmailAndPassword(auth, loginEmail, loginPassword)
})
.catch((error) => {
console.log(error.message)
})
}
This is what the example looks like in the official documentation
const auth = getAuth();
setPersistence(auth, browserSessionPersistence)
.then(() => {
// Existing and future Auth states are now persisted in the current
// session only. Closing the window would clear any existing state even
// if a user forgets to sign out.
// ...
// New sign-in will be persisted with session persistence.
return signInWithEmailAndPassword(auth, email, password);
})
.catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
});
The recommended way to get the current user is by setting an observer on the Auth object:
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
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;
// ...
} else {
// User is signed out
// ...
}
});
documentation
I am trying to add users with email and password function in Firebase but the information is not added once the sign up button is clicked. I have inserted the block of code I've written to perform this action. I'm not sure what I'm missing.The user information does not appear in the console and there is no error message. All other data that is entered works, the authentication part is the only thing that is not working correctly.
// signing new users up
const signupForm = document.querySelector('.signup');
signupForm.addEventListener('submit', (e) => {
e.preventDefault();
const email = signupForm.email.value;
const password = signupForm.password.value;
createUserWithEmailAndPassword(auth, email, password)
.then((cred) => {
// console.log('user created:', cred.user);
signupForm.reset();
})
.catch((err) => {
// console.log(err.message);
});
// logging in and out
const logoutButton = document.querySelector('.logout');
logoutButton.addEventListener('click', () => {
signOut(auth)
.then(() => {
alert('user signed out');
})
.catch((err) => {
console.log(err.message);
});
});
const loginForm = document.querySelector('.login');
loginForm.addEventListener('submit', (e) => {
e.preventDefault();
const email = loginForm.email.value;
const password = loginForm.password.value;
signInWithEmailAndPassword(auth, email, password)
.then((cred) => {
console.log('user logged in:', cred.user);
loginForm.reset();
})
.catch((err) => {
console.log(err.message);
});```
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.
I have a problem registering users in my Vue app... When a user register, I want to fire updateProfile to add more user data, and after that, in the onAuthStateChanged in my main.js save all that user data in vuex to use across my app, but the onAuthStateChanged excutes before the updateProfile, so in vuex displayName and photoURL are undefined.
How can I make the onAuthStateChanged wait to updateProfile to finish?
I have this function in my Register.vue component:
register() {
firebase
.auth()
.createUserWithEmailAndPassword(this.email, this.password)
.then(user => {
firebase
.auth()
.currentUser.updateProfile({
displayName: this.displayName,
photoURL: this.photoURL
})
.then(() => {
db.collection("users")
.doc(user.user.uid)
.set({
email: this.email,
displayName: this.displayName,
realName: this.realName,
photoURL: this.photoURL
})
.then(() => {
console.log(user);
this.$router.replace("/");
})
.catch(err => {
this.errorMessage = err.message;
});
})
.catch(err => {
this.errorMessage = err.message;
});
})
.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);
});
}
}
And have this in my main.js:
let app = "";
firebase.auth().onAuthStateChanged((user) => {
store.dispatch("fetchUser", user);
if (!app) {
new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
}
});
The reason you are getting undefined is probably because you don't return the asynchronous functions from the register method.
You currently have this
register() {
firebase // undefined as you don't return anything
.auth()
.createUserWithEmailAndPassword(this.email, this.password)
.then(user => {
firebase
.auth()
.currentUser.updateProfile({
....
})
.then(() => { // undefined as you don't return in the previous then block
db.collection("users")
.doc(user.user.uid)
.set({
......
})
.then(() => { // undefined because you don't return in the previous then block
....
})
.catch(err => {
...
});
})
.catch(err => {
....
});
})
.catch(function(error) {
....
});
}
}
Do this
import { EventBus } from './eventBus.js';
register() {
EventBus.$emit('user-registration-causes-auth-change', true) // set this to true when the registration starts so that when eventbus listens to it in main.js, it won't update user profile (alternatively, replace with let self = this)
// (if following alternative route, this.isRegistrationTriggeringAuthStateChange = true;)
return firebase
.auth()
....
.then(user => {
return firebase
.auth()
.currentUser....
.then(() => {
return db.collection("users")
....
.set({
......
})
.then(() => {
EventBus.$emit('user-registration-causes-auth-change', false) // set it to false after you have finised updating the user profile.
// if following alternative route, self.isRegistrationTriggeringAuthStateChange = false;
})
})
})
}
eventBus.js
import Vue from 'vue';
export const EventBus = new Vue(); // initialise an event bus here and export it so that it could be used in other files
Main.js
import Vue from 'vue';
import { EventBus } from './eventBus.js';
let app
auth.onAuthStateChanged(async() => {
if (!app) {
app = new Vue({
router,
store,
data: {
isRegistrationTriggeringAuthStateChange: false; // initialise it to false so that when you load the page, it won't be hindered from dispatching "fetchUser" if there's a user.
},
render: h => h(App)
}).$mount('#app')
}
EventBus.$on('user-registration-causes-auth-change', (payload) => {
app.isRegistrationTriggeringAuthStateChange = payload;
})
await Vue.$nextTick() // wait for the DOM to update
if (user && !app.isRegistrationTriggeringAuthStateChange) { // put the conditional here
store.dispatch("fetchUser", user);
}
})
EventBus.$off('user-registration-causes-auth-change', (payload) => { // this could be extracted into a handler
app.isRegistrationTriggeringAuthStateChange = payload;
})
This is rough code, but the goal is to convey the information. You can clean it up as you please.
I have a function "signInWithPhoneNumber" in SignUp screen after call it navigates me to a Confirmation Screen and I pass some params after navigate to confirm a verification code I was received,
So in this screen "Confirmation", I have a button "Re-send Verification Code" so my question is
when I press to "re-send" I want to call a "signInWithPhoneNumber" function in SignUp screen to get a new code
So what you think? that's possible?
Or rewrite a signInWithPhoneNumber in a confirmation screen and call it after pressed re-send button?
SignUp Screen - Function
signUp = async () => {
const {phoneNumber} = this.state;
this.setState({message: 'Sending code ...'});
const phoneWithAreaCode = phoneNumber.replace(/^0+/, '+972');
console.log(phoneWithAreaCode);
auth()
.signInWithPhoneNumber(phoneWithAreaCode, true)
.then(confirmResult => {
console.log('confirmResult', confirmResult);
this.setState({confirmResult, message: 'Code has been sent!'});
// this.createUserDatabase();
})
.then(() => {
this.props.navigation.navigate('Confirmation', {
message: this.state.message,
confirmResult: this.state.confirmResult,
createUser: uid => this.createUserDatabase(uid),
});
});
};
Confirmation screen - function
confirmCode = codeInput => {
const confirmResult = this.props.navigation.state.params.confirmResult
if (confirmResult && codeInput.length) {
confirmResult
.confirm(codeInput)
.then(user => {
clearInterval(this.interval);
const {params} = this.props.navigation.state;
//Check if any users exist
database()
.ref(`users`)
.limitToFirst(1)
.once('value', snapshot => {
if (snapshot.exists()) {
console.log('exists!');
return true;
} else {
params.createUser(user.uid);
console.log('No user found Hah');
}
});
this.setState({
timer: 0,
message: 'Code Confirmed!',
isValid: true,
});
})
.catch(error => {
let errorCode = error.code;
let errorMessage = error.message;
console.log(errorCode);
switch (errorCode) {
case 'auth/invalid-verification-code':
this.setState({message: 'Code is invalid', codeInput: ''});
this.refs.codeInputRef2.clear();
break;
default:
alert(`Please, Check your Messages!`);
break;
}
console.log(errorMessage);
});
} else {
console.log('Not here');
}
};
You can send signInWithPhoneNumber to Confirmation screen, while navigating to it from SignUp screen, like so
this.props.navigation.navigate('Confirmation', {
message: this.state.message,
confirmResult: this.state.confirmResult,
createUser: uid => this.createUserDatabase(uid),
signInWithPhoneNumber: signInWithPhoneNumber // your actual function here
});
});
And then this function will be available in Confirmation screen as a prop, and you can call it when necessary