gpt4 book ai didi

javascript - 试图让 firebase.auth().currentUser 成为一个 promise

转载 作者:行者123 更新时间:2023-12-04 12:37:29 26 4
gpt4 key购买 nike

当用户登录时,我试图将他们发送到受限页面。所以我通过检查用户对象来保护路由。问题在于,当用户创建或登录时,身份验证不会立即更改,因此在创建或登录后,firebase.auth().currentUser 可以返回 null 几毫秒。因此,如果我将它们发送到页面,它将返回一个错误。

这就是我试图让路由等待一段时间以查看授权是否更改的尝试。我想知道代码是否有任何问题或编写此代码的更好方法。

附:我知道我可以检查 firebase.auth().onAuthStateChanged,但我不明白如何在用户创建或登录时使用它。它只是在后台运行,我不能当 auth 在没有上下文的情况下更改时,不要只向用户发送路由。它也没有超时。

getUser( { commit } ) {
return new Promise( ( resolve, reject )=> {
let user, i = 0
function checkForUser() {
setTimeout( ()=> {
i++
user = firebase.auth().currentUser
if ( user ) {
router.push( { path: '/restricted' } )
resolve()
} else if ( i > 30 ) {
reject( { message: 'Something went wrong, please try again.' } )
} else {
checkForUser()
}
}, 100 )
}
checkForUser()
} )
},

最佳答案

这是一个很长的答案,因为 Firebase 尚未就 https://github.com/firebase/firebase-js-sdk/issues/462 做任何事情。


这是我过去的做法,在 Vuex 中同步用户。

为此,我有两个突变和一个方便的 setter/getter ,但那里没有什么特别的

state: {
user: null
},
getters: {
isAuthenticated: state => typeof state.user === 'object' && state.user !== null
},
mutations: {
LOGIN: (state, user) => (state.user = user),
LOGOUT: state => (state.user = null)
}

我有一个 firebase/index.js用于配置 Firebase 应用的文件,如下所示

import firebase from 'firebase/app'
import 'firebase/auth'
// import any other Firebase libs like firestore, etc
import config from './config'
import store from '../store' // import the Vuex store

firebase.initializeApp(config)

export const auth = firebase.auth()
// export other Firebase bits like db, etc

const onAuthStateChangedPromise = new Promise((resolve, reject) => {
auth.onAuthStateChanged(user => {
store.commit(user !== null ? 'LOGIN' : 'LOGOUT', user)
resolve(user)
}, err => {
reject(err)
})
})

export const onAuthStateInit = () => onAuthStateChangedPromise

onAuthStateChanged listener 使 store 与用户的 auth 状态保持同步,但外部 Promise 只解析一次(随后对 resolve() 的调用将被忽略)。由于 promise 的这一特性,onAuthStateChangedPromise可用于检测 Firebase 身份验证系统何时完成其初始化阶段。

然后我将该 promise 公开为一个名为 onAuthStateInit 的函数.

在我的路由器中,我使用了 meta名为 public 的标志确定路由是否可公开访问(大多数路由没有它,这意味着它们需要身份验证)。

我的全局导航守卫看起来像这样

import { onAuthStateInit } from './firebase'

// define routes, new VueRouter, etc

router.beforeEach(async (to, from, next) => {
await onAuthStateInit() // wait for auth system to initialise
if (to.matched.every(route => route.meta.public) || store.getters.isAuthenticated) {
next()
} else {
next({ name: 'sign-in' }) // redirect to sign-in page
}
})

您可以使用 await onAuthStateInit()您需要等待第一页加载身份验证初始化完成的任何地方。您可以根据需要多次调用它,它只会等待一次。身份验证初始化完成后,此 promise 将立即解决。

我的sign-in页面使用 Firebase 身份验证 UI,并定义了以下 回调

import firebase from 'firebase/app'
import * as firebaseui from 'firebaseui'
import { auth } from '../firebase'
import 'firebaseui/dist/firebaseui.css'

const ui = new firebaseui.auth.AuthUI(auth)

export default {
mounted () {
// the ref is just a <div> in my template
const container = this.$refs.firebaseuiAuthContainer
ui.start(container, {
// signInOptions, etc
callbacks: {
signInSuccessWithAuthResult: authResult => {
this.$router.push({ name: 'home' }) // go to homepage or wherever
},
signInFailure: err => {
// handle sign-in error
}
}
})
}
}

您不必使用身份验证 UI。 onAuthStateChange 将捕获对当前用户身份验证状态的任何更改。监听器,以便您可以使用手册 auth.SignInWith*()方法,如果你想。

关于javascript - 试图让 firebase.auth().currentUser 成为一个 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63047603/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com