繁体   English   中英

如何在类星体中处理firebase的onAuthStateChanged函数

[英]How to handle firebase's onAuthStateChanged function in quasar

目前我正在为一些组件和 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函数?

谢谢你的帮助

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

  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 (!storeAuth.handlingAuth) {
     await storeAuth.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()
     }
   })
 })
}
  1. 不要在 store 中使用useRouter()的错误。 useRouter()仅用于设置函数或<script setup> 您需要做的是将路由器作为插件添加到 Pinia。 所以在你的stores/index.js中导入你的路由器,然后添加:
pinia.use(({ store }) => { store.router = markRaw(router) })

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

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

总之,它的工作原理如下:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM