简体   繁体   English

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

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

Currently I'm using tailwind css and headlessui for a few components and firebase.目前我正在为一些组件和 firebase 使用 tailwind css 和 headlessui。

Now I would like to use quasar but the boot files are very mysterious to me.现在我想使用 quasar 但引导文件对我来说非常神秘。

Currently I manage firebase with config.js, main.js and pinia store.目前我用 config.js、main.js 和 pinia 商店管理 firebase。

I replaced my old config.js file with a firebase.js boot file as recommended by Quasar and it seems to work.我按照 Quasar 的建议用 firebase.js 引导文件替换了旧的 config.js 文件,它似乎可以工作。 (but I don't really know if it's good practice) (但我真的不知道这是否是好的做法)

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
})

But I don't know what to do with the old mains.js file which is no longer available in Quasar.但我不知道如何处理 Quasar 中不再可用的旧 mains.js 文件。 In main.js there is the following code:在 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')
  }
})

What should I do with the code above in particular with the onAuthStateChanged function?我应该如何处理上面的代码,尤其是onAuthStateChanged函数?

Thanks for your help谢谢你的帮助

I've found a solution for this that is suitable for my purposes.我找到了适合我目的的解决方案。 For me the requirements were:对我来说,要求是:

  1. Make sure auth is initialized on a refresh, before rendering.在渲染之前,请确保在刷新时初始化身份验证。
  2. Make sure any data required for the app is also initialized, before rendering.在渲染之前,确保应用程序所需的任何数据也已初始化。
  3. Detect log-in, log-out, and time outs and act accordingly.检测登录、注销和超时并采取相应措施。

I haven't tested time outs yet but basically I solved this with the following flow.我还没有测试超时,但基本上我通过以下流程解决了这个问题。

  1. In your router/index.js file, add a before each function, that checks to see if a listener is active, and calls a store function to create it if not.在您的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. In the auth store, make a function that returns a promise to await in the beforeEach .在 auth 商店中,创建一个函数,在beforeEach中返回一个等待等待的承诺。 Something like:就像是:
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. Don't make the mistake of using useRouter() in the store.不要在 store 中使用useRouter()的错误。 useRouter() is only for use in the setup function, or <script setup> . useRouter()仅用于设置函数或<script setup> What you need to do is add the router as a plugin to Pinia.您需要做的是将路由器作为插件添加到 Pinia。 So in your stores/index.js import your router, then add this:所以在你的stores/index.js中导入你的路由器,然后添加:
pinia.use(({ store }) => { store.router = markRaw(router) })

That way you can use this.router.push() in your store modules.这样你就可以在你的商店模块中使用this.router.push()

This might seem a bit messy because of redirects in both the navigation guard and the store action but this seems like the easiest way to get it to load the required data from both refresh and login while only using onAuthStateChanged in one place.由于导航保护和存储操作中的重定向,这可能看起来有点混乱,但这似乎是让它从刷新和登录加载所需数据的最简单方法,同时仅在一个地方使用onAuthStateChanged

In summary it works like this:总之,它的工作原理如下:

  1. When refreshed or entering a url manually, the app awaits the first state change, and any necessary loading.手动刷新或输入 url 时,应用程序等待第一次状态更改和任何必要的加载。
  2. Then in the nav guard, you can check whatever store variables you need to check your user login state, and redirect.然后在导航守卫中,您可以检查检查用户登录状态和重定向所需的任何存储变量。 Like back to the login page, if the user happened to enter a url for a members-only section.就像回到登录页面一样,如果用户碰巧输入了会员专区的 url。
  3. Subsequent navigations (non-refresh) see that the auth handling is already set up, so it is ignored.后续导航(非刷新)看到已经设置了身份验证处理,因此将其忽略。
  4. When a separate function triggers login or logout, we can see that it is not the initialLoad, and do any other redirects at that point.当一个单独的函数触发登录或注销时,我们可以看到它不是初始加载,并在此时执行任何其他重定向。

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

相关问题 Firebase onAuthStateChanged 和 Navigation Guards 的模式 - Quasar 应用 - Pattern for Firebase onAuthStateChanged and Navigation Guards - Quasar app Firebase OnAuthStateChanged函数不返回任何内容 - Firebase OnAuthStateChanged function not returning anything 如何使用Firebase的onAuthStateChanged来跟踪Angular中的用户登录状态? - How to use Firebase's onAuthStateChanged to track user login state in Angular? Firebase的set()在onAuthStateChanged()内部不起作用 - Firebase's set() not working inside onAuthStateChanged() 斐波那契数列之后,firebase onAuthStateChanged - firebase onAuthStateChanged following Fibonacci's series Firebase 身份验证 onAuthStateChanged 在函数主体后响应 - Firebase authentication onAuthStateChanged responding after function body 此 Firebase onAuthStateChanged 如何在此代码中工作 - How does this Firebase onAuthStateChanged work in this code 如何在 Firebase Auth onAuthStateChanged 中测试 setState - How to test setState inside Firebase Auth onAuthStateChanged Firebase 和 React TypeError: firebase.auth(...).onAuthStateChanged 不是 function - Firebase and React TypeError: firebase.auth(...).onAuthStateChanged is not a function Firebase 9.4.1 和 Javscript 身份验证功能“onAuthStateChanged”运行缓慢 - Firebase 9.4.1 and Javscript Authentication function "onAuthStateChanged" works slowly
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM