我正在使用Firebase身份验证构建Vue PWA。该网络应用将在首次加载的App上监听Firebase的onAuthStateChanged
事件,以通过调用Firebase的ID token
自动登录用户并保存其getIdToken(/* forceRefresh */ true)
的API请求。
除此之外,我还利用Page Visibility API在隐藏5分钟后重新加载了Web App(如果旧的Firebase ID token
已过期,则重新获得该应用)。
在Android手机上,我在Chrome上访问我的Web应用程序URL,然后将图标添加到主屏幕,并通过该图标访问Web应用程序进行所有测试。
这是测试用例:登录并正常使用Web应用程序后,单击“主页”按钮隐藏该Web应用程序,然后约10分钟后,我从后台状态调用该应用程序,该Web应用程序已自动重新加载成功后,我可以继续正常使用它。问题是,如果我在很长一段时间(〜6小时)后从后台调用该应用程序,则该网络应用程序不会自动重新加载,因此我没有新的Firebase ID Token
用户,因此我得到了提出API请求以获取用户个人资料时发生Token Expired
错误...
我需要找到一种可靠的方式来触发autoLogin()
功能,因此用户不需要每次使用WebApp回来时都重新登录。
以下是基本代码库:
main.jsconst unsubscribe = fibAuth.onAuthStateChanged((user) => {
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App },
created () {
// Firebase auto login
if (user) {
store.dispatch('autoLogin', user)
}
// Reload after a duration
document.addEventListener('visibilitychange', function () {
store.dispatch('appVisibilityHandler', document.visibilityState)
})
} // end created()
}) // end Vue()
unsubscribe()
})
Vue商店-index.js
async autoLogin ({commit, state, dispatch}, userPayload) {
commit('SET_APP_LOADING', true)
try {
let idToken = await userPayload.getIdToken(/* forceRefresh */ true)
console.warn('store::autoLogin() - idToken:', idToken)
let apiResponse = await UsersRepos.getMyProfile(idToken)
// ... processing apiResponse ...
} catch (error) {
console.error('store::autoLogin() - error:', error)
}
commit('SET_APP_LOADING', false)
},
appVisibilityHandler (context, statePayload) {
try {
const APP_REFRESH_SECONDS_THRESHOLD = 300 // 5 minutes
if (statePayload === 'hidden') {
localStorage.setItem('app-hidden-ts', (new Date()).getTime())
} else if (statePayload === 'visible') {
let lastSec = parseInt(localStorage.getItem('app-hidden-ts') / 1000)
let nowSec = parseInt((new Date()).getTime() / 1000)
localStorage.setItem('app-hidden-ts', nowSec * 1000)
console.warn('total hidden seconds:', (nowSec - lastSec))
if (nowSec - lastSec > APP_REFRESH_SECONDS_THRESHOLD) {
context.commit('SET_APP_LOADING', true)
// refresh the whole web page
router.go()
}
}
} catch (error) {
alert('appVisibilityHandler error:' + error.message)
}
}
非常感谢您提供解决此问题的指南或线索。预先谢谢您!
答案 0 :(得分:0)
Firebase身份验证使用有效期为一小时的ID令牌。调用getIdToken()
会返回此令牌。 SDK会在后台自动刷新ID令牌,但由于身份验证状态未更改,因此当然无法调用autoLogin
。
您需要附加一个onIdTokenChanged
handler来检测ID令牌何时已更改并提取。
firebase.auth().onIdTokenChanged(function(user) {
if (user) {
// User is signed in or token was refreshed.
store.dispatch('autoLogin', user)
}
});
实际上,此可能 替换您的onAuthStateChanged
处理程序,因为这在用户登录时也会触发。