Recently I started using Pinia as global storage in my Vue 3 project. I'm using Firebase for user authentication and trying to load the current user before Vue is initialized. Ideally, everything related to authentication should be in a separate file, using Pinia Store. Unfortunately (unlike Vuex), the Pinia instance needs to be passed before the Vue instance before I can use any action, and I think that's the problem. On first load, the user
object in storage is briefly empty.
This is the stored action that binds the user (using the new Firebase Web v9 Beta) in auth.js
:
import { defineStore } from "pinia"; import { firebaseApp } from "@/services/firebase"; import { getAuth, onAuthStateChanged, getIdTokenResult, } from "firebase/auth"; const auth = getAuth(firebaseApp); export const useAuth = defineStore({ id: "auth", state() { return { user: {}, token: {}, }; }, actions: { bindUser() { return new Promise((resolve, reject) => { onAuthStateChanged( auth, async (user) => { this.user = user; if (user) this.token = await getIdTokenResult(user); resolve(); }, reject() ); }); }, // ... }})
This is my main.js
file:
import { createApp } from "vue"; import App from "./App.vue"; import router from "./router"; import { createPinia } from "pinia"; import { useAuth } from "@/store/auth"; (async () => { const app = createApp(App).use(router).use(createPinia()); const auth = useAuth(); auth.bindUser(); app.mount("#app"); })();
How do I set the user before anything else happens?
P粉7953113212023-11-07 12:04:36
I figured it out. Had to register the router after the async stuff
//main.js (async () => { const app = createApp(App); app.use(createPinia()); const { bindUser } = useAuth(); await bindUser(); app.use(router); app.mount("#app"); })();