我正在尝试使用 Vue 3 和 Firebase 创建 PWA 应用程序。我必须具备的功能之一是提供离线支持,包括即使在用户的互联网连接中断时也能保持用户登录状态。
长话短说,让我们从
firebase.ts
设置开始
export const firebaseApp = initializeApp(firebaseConfig)
export const db = getFirestore()
export const auth = getAuth(firebaseApp)
enableIndexedDbPersistence(db)
.catch(err => alert(err));
然后,我执行一个操作来登录用户
async login(context, {email, password}) {
const response = await signInWithEmailAndPassword(auth, email, password)
if (response) {
context.commit("setAuth", response.user)
}
}
据我了解文档和不同的来源,通过这个简单的设置,auth 应该离线保存。
所以我在我的应用程序中添加了测试代码
<VMain>
<VBtn @click="check">Check</VBtn>
{{ userInfo }}
<RouterView class="pa-6"/>
</VMain>
import {auth} from "@/plugins/firebase";
import {ref} from "vue";
const userInfo = ref("")
async function check() {
const user = auth.currentUser
if (user) {
userInfo.value = user.uid
} else {
userInfo.value = "logged out"
}
}
它似乎在工作,我在我的 iPhone 上启动了我的应用程序,我将它添加到主屏幕,我登录然后关闭了我手机上的网络。
我能够使用我的应用程序,在不同的视图之间导航,上面引用的函数总是返回记录的用户 ID。我可以最小化我的应用程序,回到那里后它仍然可以工作。但是,一旦我删除了在后台运行的应用程序并再次重新打开它,我就被注销了。有没有办法避免这种情况并让用户保持登录状态,即使:
我有两个想法如何实现:
问题是——我是不是把事情复杂化了?也许还有其他更好且随时可用的解决方案?
使用 firebase onAuthStateChanged 侦听器并将值保存在您的商店中。
onAuthStateChanged(auth, () => {
const store = useStore();
store.setUser(auth);
});
只要用户的身份验证状态发生变化,它就会相应地更新商店。 然后,您可以利用 Vue 反应性来相应地更新 UI。
就 PWA 方面而言 - 当然,您需要在线才能最初加载应用程序。加载应用程序并将用户身份验证保存在商店中后,即使应用程序进入后台并处于离线状态也没有问题。如果经过的时间足够短,您将能够像从未离开过应用程序一样打开应用程序并使用它。我的经验是,大约 6 小时后,需要完全重新加载,此时您需要在线。这是根据我的经验。希望对您有所帮助!
与 Firestore 一样,Authentication 有自己的功能来开启持久性。
import { getAuth, setPersistence, signInWithEmailAndPassword, browserSessionPersistence } from "firebase/auth";
const auth = getAuth();
setPersistence(auth, browserSessionPersistence)
.then(() => {
// Existing and future Auth states are now persisted in the current
// session only. Closing the window would clear any existing state even
// if a user forgets to sign out.
// ...
// New sign-in will be persisted with session persistence.
return signInWithEmailAndPassword(auth, email, password);
})
.catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
});
更多信息doc