您好stackoverflow社区,我的第一篇文章!
在这篇文章的开头,我会说我不是软件工程师或开发人员,而是谦虚的业余爱好者(应该选择一个更轻松的业余爱好)。所以这个问题纯粹是出于兴趣。
场景: 我在前端使用物化来弹出模式,用户可以登录,注销和注册,并根据需要根据登录状态隐藏链接。
我在我的navbar vue js组件的已安装生命周期挂钩中有onAuthStateChanged观察器,可以很好地监视身份验证状态。
到目前为止,一切都很好,我的登录和注销工作正常,我用user.displayName填充了current_user变量。但是,当我注册onAuthStateChanged触发器,但current_user设置为null时。尽管我的if(user)语句评估为true。
firebase.auth().onAuthStateChanged((user) => {
if(user) {
console.log(user)
// User is signed in.
this.current_user = user.displayName
console.log(user.displayName)
} else {
this.current_user = null
console.log('no current user')
}
})
这在逻辑上对我来说毫无意义,除非用户评估为真,否则我将无法访问if语句的这一部分。而且我已经在控制台中记录了用户令牌,因此它显然存在。该死,我可以在控制台中打开它,并看到它有一个displayName。
我认为问题可能与
的异步性质有关
cred.user.updateProfile({
displayName: this.signup_username
})
但是事实是,控制台在记录用户令牌,并且我可以清楚地看到该令牌中的显示名称,这让我scratch不解为什么下一个console.log将返回null。而且,除非用户评估为true,否则我什至无法访问if函数。
是的,我知道我可以在集合中为显示名称设置一个字段,查询数据库抓取该字段并显示它,但是当auth令牌预先包装有专门用于此目的的显示名称时,我可能应该拒绝?
所以我的实现模态组件中的注册方法。
methods: {
sign_up() {
//check if all fields have been entered
if(this.signup_email && this.signup_password && this.signup_username) {
//check to see if the username exists, using username as document ID as they have to be unique
let ref = db.collection('users').doc(this.signup_username)
ref.get().then(doc => {
if(doc.exists) {
//username already exists, warn user
this.feedback='This username already exists'
} else {
this.feedback = 'this username is free to use'
//continue with signup if username is unique
firebase.auth().createUserWithEmailAndPassword(this.signup_email, this.signup_password).then((cred) => {
//set the display name of the user auth token to be the sign up username
cred.user.updateProfile({
displayName: this.signup_username
})
//make a user record in the database
ref.set({
email: this.signup_email,
password: this.signup_password,
user_id: cred.user.uid
})
}).then(() => {
//reset form fields and close the modal
this.signup_email = null
this.signup_password = null
this.signup_username = null
let sig_modal = document.querySelector('#modal-signup')
M.Modal.init(sig_modal).close()
}).catch(err => {
this.feedback = err.message
})
}
})
} else {
this.feedback = 'Yo you must fill in the fields'
}
}
和我在navbar组件中安装的生命周期挂钩,在该组件中,我具有当前登录的用户的显示名称可见。并根据current_user为true或false(null或user.displayName)隐藏和显示功能
<script>
import firebase from 'firebase'
import sign_up_modal from './sign_up_modal.vue'
import login_modal from './login_modal.vue'
import account_modal from './account_modal.vue'
import create_char_modal from './create_char_modal.vue'
import confirmation_modal from './confirmation_modal'
export default {
name: 'navbar_top',
data() {
return {
current_user: null
}
},
methods: {
logout() {
firebase.auth().signOut().then(() => {
//notify logout success
})
}
},
components: {
sign_up_modal,
login_modal,
account_modal,
create_char_modal,
confirmation_modal
},
mounted() {
// initialize materialize elements
document.addEventListener('DOMContentLoaded', function() {
let modals = document.querySelectorAll('.modal');
M.Modal.init(modals);
let items = document.querySelectorAll('.collapsible');
M.Collapsible.init(items);
})
firebase.auth().onAuthStateChanged((user) => {
if(user) {
console.log(user)
// User is signed in.
this.current_user = user.displayName
console.log(user.displayName)
} else {
this.current_user = null
console.log('no current user')
}
})
}
}
</script>
现在是问题,它可以用于登录和注销,当前用户使用user.displayName填充,但由于某种原因而不是注册(createUserWithEmailAndPassword)。为了使事情变得更加奇怪,我可以在注册后console.log用户令牌,因为我的onAuthStateChanged观察者会触发if(user)。可以肯定的是,我可以在控制台中打开令牌,并且确实设置了displayname。但是我的下一个console.log console.log(user.displayName)返回null。这是我默认设置为current_user的内容。如果我手动刷新页面,瞧,就可以了。
预期结果:current_user变量中填充了user.displayName。使用登录功能成功完成。
控制台中没有错误消息,所有相关的数据库活动都在起作用。它在firebase的身份验证区域中创建一个用户,并在数据库的users集合中创建一个条目。