[英]Pattern for Firebase onAuthStateChanged and Navigation Guards - Quasar app
[英]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
函数?
谢谢你的帮助
我找到了适合我目的的解决方案。 对我来说,要求是:
我还没有测试超时,但基本上我通过以下流程解决了这个问题。
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()
})
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()
}
})
})
}
useRouter()
的错误。 useRouter()
仅用于设置函数或<script setup>
。 您需要做的是将路由器作为插件添加到 Pinia。 所以在你的stores/index.js
中导入你的路由器,然后添加:pinia.use(({ store }) => { store.router = markRaw(router) })
这样你就可以在你的商店模块中使用this.router.push()
。
由于导航保护和存储操作中的重定向,这可能看起来有点混乱,但这似乎是让它从刷新和登录加载所需数据的最简单方法,同时仅在一个地方使用onAuthStateChanged
。
总之,它的工作原理如下:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.