Vue Vuex Firebase Auth email sign in and update username - firebase

I've got firebase auth setup, however, I'm trying to update username before setting that to my current state. When I run everything before the update, everything works fine, but I dont have a username. I'm fairly new with js promises so I've tried running the function and returning the function, neither have really worked. My expectation is that by the time the dashboard screen shows, that the username is set.
Below is the code for signup via email which works without username.
store/user/index.js
signUserUp ({commit}, payload) {
commit('setLoading', true)
commit('clearError')
firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password)
.then(function (user) {
return user.updateProfile({
displayName: payload.username
})
})
.then(
profile => {
commit('setLoading', false)
const newUser = {
id: profile.uid,
name: profile.username,
email: profile.email,
photoUrl: profile.photoURL
}
commit('setUser', newUser)
}
)
.catch(
error => {
commit('setLoading', false)
commit('setError', error)
console.log(error)
}
)
}
This is the code that returns an error and does not update the username until I refresh.
signUserUp ({commit}, payload) {
commit('setLoading', true)
commit('clearError')
firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password)
.then(function (user) {
return user.updateProfile({
displayName: payload.username
})
.then(
profile => {
commit('setLoading', false)
const newUser = {
id: profile.uid,
name: payload.username,
email: profile.email,
photoUrl: profile.photoURL
}
commit('setUser', newUser)
}
)
.catch(
error => {
commit('setLoading', false)
commit('setError', error)
console.log(error)
}
)
},
My view is really simple just displaying the data.
<template>
<div>
<h1>Dashboard</h1>
<button #click="onLogout">Logout</button>
<hr>
<app-alert v-if="error" #dismissed="onDismissed" :text="error.message"></app-alert>
<img :if="user.photoURL" :src="user.photoUrl">
<h4><b>Display Name :</b> {{ user.name }}</h4>
<h4><b>Email :</b> {{ user.email }}</h4>
<h4><b>Email Verified :</b> {{ user.emailVerified }}</h4>
<h4><b>User ID :</b> {{ user.id }}</h4>
</div>
</template>
<script>
export default {
date () {
return {}
},
computed: {
user () {
return this.$store.getters.user
},
error () {
return this.$store.getters.error
}
},
methods: {
onLogout () {
this.$store.dispatch('logout')
this.$router.push('/')
},
onDismissed () {
this.$store.dispatch('clearError')
}
}
}
</script>
The errors I get back are an alert that states
Cannot read property 'uid' of undefined
And also, username does not display on the page component, even though it does display on page refresh.
Everything works fine up until I add this bit to try and update the username on user create, so this little bit doesn't pass the new updated user object.
.then(function (user) {
return user.updateProfile({
displayName: payload.username
})
})

Looks like my problem was in how I was sequencing my functions, in place of returning the user.updateProfile function, I was able to nest my updateProfile call like below, additionally, I was calling username as the object username when it should've been displayName.
signUserUp ({commit}, payload) {
commit('setLoading', true)
commit('clearError')
firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password)
.then(function (user) {
user.updateProfile({
displayName: payload.username
}).then(
() => {
commit('setLoading', false)
const newUser = {
id: user.uid,
name: user.displayName,
email: user.email,
emailVerified: user.emailVerified
}
commit('setUser', newUser)
}
).catch(
error => {
commit('setLoading', false)
commit('setError', error)
console.log(error)
}
)
})
.catch(
error => {
commit('setLoading', false)
commit('setError', error)
console.log(error)
}
)
},

Related

Firebase signInWithRedirect() not preserving Vue route params

I have a Pricing page which has a pricing table and does the following to redirect to a Sign Up page with a route param which determines which price (product) the user picked:
methods: {
subscribe(price) {
this.loading = true;
if (!this.loggedIn) {
this.$router.push({ name: "Sign Up", params: { price: price } });
}
},
},
In the Sign Up component, it will console log the correct price from the route param in mounted , but after the signIn with google happens and it redirects to the Checkout component, the route param price is lost:
mounted: function () {
const googleAuth = new firebase.auth.GoogleAuthProvider();
if (!this.loggedIn) {
firebase.auth().signInWithRedirect(googleAuth);
firebase
.auth()
.getRedirectResult()
.then((result) => {
this.$router.push({ name: "Checkout", params: { price: this.$route.params.price } });
console.log(result);
})
.catch((error) => {
console.log(error);
});
firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.loggedIn = true;
} else {
// Show sign in screen with button above.
}
});
}
},

How to sign up only the users who have verified their email addresses using the email link in Firebase vue?

please help me to fix where I did wrong. the code is running successfully but not working. not getting any mail from firebase
anybody done it?
<script>
import { db } from '../plugins/firebase'
import firebase from 'firebase/app'
import '#firebase/auth'
export default {
data: function () {
return {
user: {
fname: '',
email: '',
password: '',
course: '',
phoneno: '',
error: ''
}
}
},
methods: {
pressed: function () {
db.collection('user').add(this.user).then(() => {
this.user.fname = ''
this.user.email = ''
this.user.password = ''
this.user.phoneno = ''
this.user.course = ''
})
firebase
.auth()
.createUserWithEmailAndPassword(this.user.email, this.user.password)
const actionCodeSettings = {
url: 'https://www.naviclearn.com/evolveI',
handleCodeInApp: true
}
firebase.auth().currentUser.sendEmailVerification(actionCodeSettings)
.then(data => {
alert('User successfully created!')
console.log(data)
this.$router.push({ name: 'evolveGo' })
})
.catch(error => {
this.error = error.message
})
}
}
}
</script>
please help me to fix where I did wrong. the code is running successfully but not working. not getting any mail from firebase
anybody done it?

Maximum call stack size exceeded( in Nuxt + Firebase Project)

I'm currently creating an authentication feature in Nuxt and Firebase.
The login and logout process itself can be done and the header display changes accordingly, but there is an error in console when I press the login button.
Error content (in console)
Uncaught RangeError: Maximum call stack size exceeded
at Function.keys (<anonymous>)
code
Header.vue(This is the page containing the login button.)↓
googleLogin () {
const provider = new firebase.auth.GoogleAuthProvider()
auth.signInWithPopup(provider)
.then(res => {
this.dialogAuthVisible = false
this.$store.dispatch('auth/setUser',res.user)
}).catch(e => console.log(e))
}
store/auth.js↓
export const strict = false
export const state = () => ({
user: null
})
export const mutations = {
SET_USER (state, payload) {
state.user = payload
}
}
export const actions = {
setUser ({ commit }, user) {
commit('SET_USER',user)
}
}
export const getters = {
isAuthenticated (state) {
return !!state.user
}
}
default.vue↓
mounted () {
auth.onAuthStateChanged(user => {
const { uid, displayName, photoURL} = user
if (user) {
this.$store.dispatch('auth/setUser', { uid, displayName, photoURL})
} else {
this.$store.dispatch('auth/setUser', null)
}
})
}
If there's any information I'm missing, please let me know 🙇️.
Please teach me how to do this 🙇️.
I think the problem is in this code lines :
export const mutations = {
SET_USER (state, payload) {
state.user = payload
}
}
export const actions = {
setUser ({ commit }, user) {
commit('SET_USER',user)
}
}
There is a loop between this mutations and actions
Instead of setting the entire payload into the store object, I just picked the fields I needed, and that resolved the problem for me.
Before:
AUTH_STATUS_CHANGED ({commit}, data: any): any {
if (data && data.authUser) {
commit('SetAuthUser', data.authUser);
} else {
commit('SetAuthUser', null);
}
}
After:
AUTH_STATUS_CHANGED ({commit}, data: any): any {
if (data && data.authUser) {
const user = data.authUser;
commit('SetAuthUser', {
uid: user.uid,
email: user.email,
emailVerified: user.emailVerified,
displayName: user.displayName,
isAnonymous: user.isAnonymous,
photoURL: user.photoURL,
stsTokenManager: user.stsTokenManager,
createdAt: user.createdAt,
lastLoginAt: user.lastLoginAt,
apiKey: user.apiKey,
});
} else {
commit('SetAuthUser', null);
}
}
Inside the mutation, just add the value received from the mutation payload.

Data does not gets added to database after adding email and password in authorization in firebase through vue.js

Data does not get added to database after adding email and password in authorization in Firebase through vue.js.
After:
firebase.auth().createUserWithEmailAndPassword(this.email, this.password)
This doesn't get executed:
ref.set({
alias: this.alias,
geolocation: null,
user_id: cred.user.uid
})
Email and Password gets added to Authorization. But other fields like alias, geolocation, user_id does not get added to the database.
import slugify from 'slugify'
import db from '#/firebase/init'
import firebase from 'firebase'
export default {
name: 'Signup',
data(){
return {
email: null,
password: null,
alias: null,
feedback: null,
slug: null,
}
},
methods: {
signup() {
if(this.alias && this.email && this.password) {
this.feedback = null
this.slug = slugify(this.alias, {
replacement: '-',
remove: /[$*_+~.()'"!\-:#]/g,
lower: true
})
let ref = db.collection('users').doc(this.slug)
ref.get().then(doc => {
if(doc.exists){
this.feedback = 'This alias already exists'
}
else {
firebase.auth().createUserWithEmailAndPassword(this.email, this.password)
.then(cred => {
ref.set({
alias: this.alias,
geolocation: null,
user_id: cred.user.uid
})
}).then(() => {
this.$router.push({ name: 'GMap' })
})
.catch(err => {
console.log(err)
this.feedback = err.message
})
}
})
} else {
this.feedback = 'You must enter all fields'
}
}
}
}
One solution could be to use cloud functions to write to the database on userCreate
https://firebase.google.com/docs/functions/auth-events

firebase auth in nuxt store module mode

Since converting from Vuex classic to module mode, my login function is broken
index.vue login interface
login() {
if (this.$refs.loginForm.validate()) {
const email = this.loginData.email
const password = this.loginData.password
this.$notifier.showMessage({ text: 'Logging in', color: 'primary' })
this.$store.dispatch('user/userLogin', { email, password }).then(
(result) => {
//
},
(error) => {
this.$notifier.showMessage({ text: error, color: 'error' })
}
)
}
store/user.js mutations
const state = () => ({
user: null,
isAuthenticated: false
})
const mutations = {
setUser(state, payload) {
state.user = payload
},
setIsAuthenticated(state, payload) {
state.isAuthenticated = payload
}
}
store/user.js login action
userLogin({ commit }, { email, password }) {
return new Promise((resolve, reject) => {
auth
.signInWithEmailAndPassword(email, password)
.then((user) => {
console.log('logged in')
commit('setUser', user)
commit('setIsAuthenticated', true)
this.$router.push({
name: 'home'
})
resolve(true)
})
.catch((error) => {
commit('setUser', null)
commit('setIsAuthenticated', false)
this.$router.push({
path: '/'
})
reject(error)
})
})
},
When the login is clicked, the console is flooded with errors like
client.js?06a0:77 Error: [vuex] do not mutate vuex store state outside mutation handlers.
at assert (vuex.esm.js?2f62:90)
at Vue.store._vm.$watch.deep (vuex.esm.js?2f62:789)
at Watcher.run (vue.runtime.esm.js?2b0e:4568)
at Watcher.update (vue.runtime.esm.js?2b0e:4542)
at Dep.notify (vue.runtime.esm.js?2b0e:730)
at B.reactiveSetter [as a] (vue.runtime.esm.js?2b0e:1055)
at Tb (auth.esm.js?b7aa:27)
at B.k.Oc (auth.esm.js?b7aa:26)
at lc (auth.esm.js?b7aa:29)
at hc (auth.esm.js?b7aa:29)
It seems to have to do with the commit('setUser', user). As i am using v-model for the inputs (email,password) I tried slice() / making a copy of the input values to no effect. What am i missing here?
EDIT: Added template
<template>
...
<v-card-text>
<v-form
ref="loginForm"
v-model="valid"
lazy-validation
#submit.prevent="login()"
>
<v-text-field
v-model="loginData.email"
label="Email"
autofocus
clearable
:rules="[rules.required, rules.length]"
prepend-icon="mdi-account-circle"
#blur="resetValidation()"
/>
<v-text-field
v-model="loginData.password"
:type="showPassword ? 'text' : 'password'"
label="Password"
:rules="[rules.required]"
prepend-icon="mdi-lock"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
#click:append="showPassword = !showPassword"
#blur="resetValidation()"
/>
...

Resources