【问题标题】:Wrap a Vue.js Firebase-Object into onAuthStateChanged handler?将 Vue.js Firebase-Object 包装到 onAuthStateChanged 处理程序中?
【发布时间】:2020-08-24 23:32:22
【问题描述】:

我正在使用 GoogleFirebase 和用于 firebase 的 Vuefire 插件实现 Vue.js Web 应用程序。我必须将 Vue.js Firebase-Object 包装到 Firebase onAuthStateChanged 函数中,以通过登录用户 uid 从实时数据库中获取数据。登录是用 Vue-Router 实现的。以下代码应该解释我的问题,我希望有人可以帮助我解决我的问题。

这不起作用,我收到 UID Of Null 错误。

firebase: {
    tableTennisData: db.ref(auth.currentUser.uid).child('tableTennis'),
},

此函数通过按钮调用,将正确的用户 ID 记录到控制台中。

methods: {
    test: function(){
        console.log(auth.currentUser.uid);
        this.uid = auth.currentUser.uid;
    },
}

但如果这在没有“onAuthStateChanged”处理程序的情况下工作,为什么使用 Firebase-Object 的实现不起作用?

这就是我将数据推送到 firebase 的方式,并且由于 firebase 云函数中的“onAuthStateChanged”处理程序而运行良好。

auth.onAuthStateChanged(function (){
   db.ref(auth.currentUser.uid).child('tableTennis').push(obj);
});

我真的需要一种方法来访问用户 uid 推送的数据。我认为我们可以通过将 Firebase-Object 包装到“onAuthStateChanged”处理程序中来解决该错误。

总结一下,这就是Vue-Router文件的登录功能。

const router = new VueRouter({
  routes
});

router.beforeEach((to, from, next) =>{
  const currentUser = auth.currentUser;
  const requiresAuth = to.matched.some(record => record.meta.requiresAuth);

  if(requiresAuth && !currentUser){
    next('/login');
   }else if(!requiresAuth && currentUser){
     next('/home');
  }else{
    next();
  }
});
export default router;

最后,这是 main.js 文件。

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import firebase from "firebase";
import './firebase';

import { rtdbPlugin } from 'vuefire'
Vue.use(rtdbPlugin);

Vue.config.productionTip = false;

let app = '';

firebase.auth().onAuthStateChanged(() =>{
  if(!app){
    app = new Vue({
      router,
      render: h => h(App)
    }).$mount("#app");
  }
});

另一个 firebase.js 文件导出变量 auth 等于 firebase.auth() 和 db 等于 firebase.database。

import { initializeApp } from 'firebase';

  const firebase = initializeApp({
    apiKey: "",
    authDomain: "",
    databaseURL: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
  });

  export const db = firebase.database();
  export const auth = firebase.auth();

已删除此问题的 API 信息。

我希望这些信息足以帮助我解决这个问题。

谢谢。

firebase: {
    tableTennisData: db.ref(auth.currentUser.uid).child('tableTennis'),
},

错误 UID 为 Null。

【问题讨论】:

    标签: javascript firebase vue.js firebase-realtime-database vue-router


    【解决方案1】:

    问题可能在于您如何配置和初始化 firebase。

    最好使用渐进增强,这样您就可以在需要时访问所需的服务。

    将您的 firebase.js 配置文件更改为以下内容

    // Firebase App (the core Firebase SDK) is always required and
    // must be listed before other Firebase SDKs
    import * as firebase from "firebase/app";
    
    // Add the firebase services that you want to use
    import "firebase/database";
    import "firebase/auth";
    
    // Initialize firebase
    const firebaseConfig = {
        apiKey: "",
        authDomain: "",
        databaseURL: "",
        projectId: "",
        storageBucket: "",
        messagingSenderId: "",
        appId: "",
        measurementId: ""
    };
    
    const fb = firebase.initializeApp(firebaseConfig);
    const db = firebase.database();
    
    // export firebase services
    export { db, fb };
    

    接下来将您的main.js 更改为以下内容

    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router";
    import { fb } from "firebase"; // your firebase services live here (auth)
    require("firebase/database"); // !important
    
    import { rtdbPlugin } from 'vuefire'
    Vue.use(rtdbPlugin);
    
    Vue.config.productionTip = false;
    
    let app = '';
    
    firebase.auth().onAuthStateChanged(() =>{
      if(!app){
        app = new Vue({
          router,
          render: h => h(App)
        }).$mount("#app");
      }
    });
    
    

    接下来将路由器文件中的路由保护逻辑更改为以下内容

    import { fb } from "../firebase.js";
    const router = new VueRouter({
      routes
    });
    
    // check if route requiresAuth
    router.beforeEach((to, from, next) => {
      if (to.matched.some(rec => rec.meta.requiresAuth)) {
        const user = fb.auth().currentUser;
        // check auth state of user
        if (user) {
          next(); // user signed in, proceed to route
        } else {
          next('/login'); // user not signed in, route to login
        }
      } else {
        next(); // route does not require auth
      }
    });
    
    export default router;
    
    

    最后你应该可以像这样访问uid了

    firebase: {
        tableTennisData: db.ref(fb.auth().currentUser.uid).child('tableTennis'),
    }
    
    

    请记住,fb 现在包含您的 firebase 服务,db 现在指的是您选择的数据库 (firestore/rtdb)。

    所以你可以像这样访问你的 firebase 服务

    fb.auth()
    fb.storage()
    fb.analytics()
    

    你会像这样访问你的 rtdb

    db.ref.('/users/' + uid)
    

    希望这会有所帮助。

    【讨论】:

    • 感谢您的全面回答。我会试试这个。但是您是否也认为我可以在函数中而不是在 Firebase-Object 中调用“auth.currentUser.uid”很奇怪?你能解释一下吗?
    • 不知道为什么,但请查看此文档 => firebase.google.com/docs/reference/js/firebase.auth.Auth#app。对于 auth 接口,文档说不要直接调用这个构造函数。相反,请使用 firebase.auth()。所以我想调用 auth.someobject 会给我们带来一些问题。
    • 这对我来说很有意义。感谢您的回答。
    猜你喜欢
    • 2021-06-30
    • 2022-07-18
    • 2011-09-13
    • 2020-08-26
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 2022-12-31
    相关资源
    最近更新 更多