用户在 Vue.js 和 Firebase 中注册后更改导航栏的状态

Posted

技术标签:

【中文标题】用户在 Vue.js 和 Firebase 中注册后更改导航栏的状态【英文标题】:Changing state of navbar after user signs up in Vue.js and Firebase 【发布时间】:2021-10-19 22:03:52 【问题描述】:

我目前正在开发一个简单的 Vue.js 应用程序,用户可以在其中注册和登录。对于登录和注册操作,我正在使用 Firebase 身份验证。到目前为止,我已经设法让用户成功登录并更改导航栏状态:当用户注销时,它显示 2 个按钮:一个登录按钮,另一个是注册按钮。当用户登录时,这些按钮将替换为用户名和退出选项。 问题在于注册选项:填写表单并按下提交后,导航栏状态发生了变化,显示了退出选项,但没有显示用户名。我想显示用户名和退出按钮,或者让应用程序在用户注册后不立即登录。有办法吗?

注册表单脚本:

import firebase from "firebase";

export default 
  name: 'Sign-Up',
  components: 
  ,
  data() 
    return 
      form: 
        errors: [],
        name: "",
        email: "",
        username: "",
        password: ""
      ,
      error: null
    ;
  ,
  methods: 
    submit() 
      firebase
        .auth()
        .createUserWithEmailAndPassword(this.form.email, this.form.password)
        .then(data => 
          data.user
            .updateProfile(
              displayName: this.form.name
            )
            .then(() => )
            .then(this.$router.replace( name: "Profile" ))
        )
        .catch(err => 
          this.error = err.message;
        );
    
  

导航栏

        <template v-if="user.loggedIn">
          <ul class="nav col-12 col-md-auto mb-2 justify-content-center mb-md-0">
            <li style="margin-top: 0.5em;"><router-link to="/Dashboard" class="nav-link px-2">Hello, user.data.displayName</router-link></li>
            <li><a href="#" class="nav-link px-2" @click.prevent="signOut"><button type="button" class="btn poke-secondary me-2">Sign out</button></a></li>
          </ul>
        </template>
        <template v-else>
          <div class="col-md-3 text-end px-2">
            <router-link to="/login"><button type="button" class="btn poke-secondary me-2">Login</button></router-link>
            <router-link to="/signup"><button type="button" class="btn poke-secondary">Sign Up</button></router-link>
          </div>
        </template>

<script>
import  mapGetters  from "vuex";
import firebase from "firebase/app";
export default 
  name: "Header",
  computed: 
    ...mapGetters(
      user: "user"
    )
  ,
  methods: 
    signOut() 
      firebase
        .auth()
        .signOut()
        .then(() => 
          this.$router.replace(
            name: "Home"
          );
        );
    
  
;
</script>

store.js:

import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store(
  state: 
    user: 
      loggedIn: false,
      data: null
    
  ,
  getters: 
    user(state)
      return state.user
    
  ,
  mutations: 
    SET_LOGGED_IN(state, value) 
      state.user.loggedIn = value;
    ,
    SET_USER(state, data) 
      state.user.data = data;
    
  ,
  actions: 
    fetchUser( commit , user) 
      commit("SET_LOGGED_IN", user !== null);
      if (user) 
        commit("SET_USER", 
          displayName: user.displayName,
          email: user.email
        );
       else 
        commit("SET_USER", null);
      
    
  
);

【问题讨论】:

您可能希望返回一个在用户数据完全可用时解决的承诺。 Firebase 响应是异步的,因此可能不会立即可用。 【参考方案1】:

我想显示用户名以及退出 按钮,或应用程序在用户之后不立即登录 注册。有办法吗?

如doc 中所述,使用createUserWithEmailAndPassword() 方法,“成功创建用户帐户后,此用户也将登录到您的应用程序”。

因此,没有办法避免用户“在用户注册后”立即登录。您的问题来自 updateProfile() 方法是异步的事实:在更新 displayName 之前有一个小的延迟。您应该处理这种情况,例如,仅当displayName 不为空时才显示Hello, user.data.displayName 字符串和“退出”按钮。

【讨论】:

【参考方案2】:

正如@Renaud 解释的那样,用户将在createUserWithEmailAndPassword 方法解决后立即登录,仅当displayName 不为空时呈现该div,v-if="user.data.displayName !== null" 可以做到这一点。

如果您真的不希望延迟呈现用户名,则另一种方法是使用Cloud function 创建新用户。由于用户是在云功能中使用Admin SDK 创建的,因此他们不会在客户端上登录。一个简单的可调用函数是:

exports.createNewUser = functions.https.onCall((data, context) => 
  const email, password, displayName = data
  
  return admin.auth().createUser( email, password, displayName ).then((userRecord) => 
    console.log('Successfully created new user:', userRecord.uid);
    return data: userRecord.uid
  ) 
);

此函数将使用提供的凭据和用户名创建一个新用户。您可以从您的 Vue 应用程序中调用此函数,如下所示:

methods: 
  submit() 
    const createUser = firebase.functions().httpsCallable('createNewUser');
    createNewUser( 
      email: this.form.email, 
      password: this.form.password,
      displayName: this.form.name
    ).then((result) => 
      const result = result.data;

      // Manually sign in user now
      // signInWithEmailAndPassword(this.form.email, this.form.password)
    );
  

【讨论】:

以上是关于用户在 Vue.js 和 Firebase 中注册后更改导航栏的状态的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 和 Firebase “用户”信息

如何在vue js项目中检测用户的firebase身份验证登录状态?

Vue.js 和 Firebase:删除了一个测试用户,现在所有路由都无法访问并且组件不呈现

如何在验证电子邮件之前阻止 Firebase/Vue.js 中的用户身份验证

Vue.js firebase 实例 - 用户 UID 作为数据库引用

在哪里放置代码以在 Vue.js 中设置 Firebase 身份验证状态持久性?