【问题标题】:How to handle firebase's onAuthStateChanged function in quasar如何在类星体中处理firebase的onAuthStateChanged函数
【发布时间】:2022-07-18 18:48:33
【问题描述】:

目前我正在为一些组件和 firebase 使用 tailwind css 和 headlessui。

现在我想使用 quasar 但启动文件对我来说很神秘。

目前我使用 config.js、main.js 和 pinia 商店管理 firebase。

我按照 Quasar 的建议用 firebase.js 引导文件替换了旧的 config.js 文件,它似乎可以工作。 (但我真的不知道这是否是好的做法)

import { boot } from 'quasar/wrappers'

import { initializeApp } from 'firebase/app'
import { getFirestore } from 'firebase/firestore'
import { getAuth } from 'firebase/auth'

const firebaseConfig = {
  apiKey: 'xxxxxxxxxxxxxx',
  authDomain: 'xxxxxxxxxxxxxx',
  projectId: 'xxxxxxxxxxxxxx',
  storageBucket: 'xxxxxxxxxxxxxx',
  messagingSenderId: 'xxxxxxxxxxxxxx',
  appId: '1:xxxxxxxxxxxxxx'
}

// Init firebase
initializeApp(firebaseConfig)

// Init services
const db = getFirestore()
const auth = getAuth()
export { db, auth }

// "async" is optional;
// more info on params: https://v2.quasar.dev/quasar-cli/boot-files
export default boot(async (/* { app, router, ... } */) => {
  // something to do
})

但我不知道如何处理 Quasar 中不再可用的旧 mains.js 文件。在 main.js 中有如下代码:

import { createApp, markRaw } from 'vue'
import router from './router/router'
import { createPinia } from 'pinia'

import App from './App.vue'

// firebase
import { auth } from './firebase/config'
import { onAuthStateChanged } from 'firebase/auth'

import './input.pcss'

let app

onAuthStateChanged(auth, () => {
  if (!app) {
    app = createApp(App)
      .use(
        createPinia().use(({ store }) => {
          store.$router = markRaw(router)
        })
      )
      .use(router)
      .mount('#app')
  }
})

我应该如何处理上面的代码,尤其是 onAuthStateChanged 函数?

感谢您的帮助

【问题讨论】:

    标签: javascript firebase vuejs3 quasar-framework


    【解决方案1】:

    我找到了适合我的目的的解决方案。对我来说,要求是:

    1. 确保在刷新之前初始化身份验证,然后再渲染。
    2. 确保应用所需的所有数据在渲染之前也已初始化。
    3. 检测登录、注销和超时并采取相应措施。

    我还没有测试超时,但基本上我通过以下流程解决了这个问题。

    1. 在您的 router/index.js 文件中,在每个函数之前添加一个,用于检查侦听器是否处于活动状态,如果没有,则调用存储函数来创建它。
     Router.beforeEach(async (to, from, next) => {
       // Access a store where you check if the auth changes are being handled
       const storeAuth = useAuth()
       if (!auth.handlingAuth) {
         await auth.handleAuth()
       }
       // Redirects as necessary using to.path and next
       next()
     })
    
    
    1. 在 auth 存储中,创建一个函数,该函数返回一个在 beforeEach 中等待的承诺。比如:
    async handleAuth() {
     const auth = getAuth()
     return new Promise((resolve) => {
       let initialLoad = true
       auth.onAuthStateChanged(async (user) => {
         if (user) {
           await this.initializeUserData()
         } else {
           await this.clearUserData()
         }
         // If it is not initial load, use the router to push
         // depending on whether the user exists.
         // if (user && !initialLoad) this.router.push('/members')
         // This would detect a login and go to the members section.
    
         // If it is the initial load, resolve the promise
         // so the router proceeds
         if (initialLoad) {
           initialLoad = false
           this.handlingAuth = true
           resolve()
         }
       })
     })
     return
    }
    
    1. 不要在商店里错误地使用useRouter()useRouter() 仅用于设置功能,或<script setup>。您需要做的是将路由器作为插件添加到 Pinia。所以在你的stores/index.js 中导入你的路由器,然后添加:
    pinia.use(({ store }) => { store.router = markRaw(router) })
    

    这样您就可以在您的商店模块中使用this.router.push()

    由于导航守卫和存储操作中的重定向,这可能看起来有点混乱,但这似乎是让它从刷新和登录加载所需数据的最简单方法,同时仅在一个地方使用onAuthStateChanged .

    总而言之,它的工作原理是这样的:

    1. 当刷新或手动输入网址时,应用会等待第一次状态更改以及任何必要的加载。
    2. 然后在导航守卫中,您可以检查您需要检查用户登录状态和重定向的任何存储变量。就像回到登录页面一样,如果用户碰巧输入了会员专区的网址。
    3. 后续导航(非刷新)发现已设置身份验证处理,因此将其忽略。
    4. 当单独的函数触发登录或注销时,我们可以看到它不是初始加载,并在此时执行任何其他重定向。

    【讨论】:

      猜你喜欢
      • 2021-03-02
      • 1970-01-01
      • 2020-05-17
      • 2020-08-24
      • 2017-06-23
      • 2018-06-22
      • 2022-07-23
      • 2021-10-28
      • 2021-06-30
      相关资源
      最近更新 更多