JaWas
JaWas

Reputation: 43

Vue 3 + Firebase onAuthStateChanged mount

I am following a tutorial for Vue that uses the following code:

let app
auth.onAuthStateChanged(() => {
  if (!app) {
    app = new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
  }
})

This is supposed to make sure that Firebase loads the authState before mounting the app, if a user reloads the page.

However, I am using Vue 3 and the thus I can't initialize via new Vue() anymore, as you have to use createApp now. I'm initializing & mounting my app the following way:

createApp(App).use(store).use(router).mount('#app')

Unfortunately, I am lost on how I can make sure that the DB still initializes the same way, and I was unable to find a proper solution (spent the last hour on google & SO).

Any help is highly appreciated, maybe I am just missing a simple concept for promises or something similar.

Thank you very much, stay healthy!

Upvotes: 2

Views: 1761

Answers (2)

Zack Heisenberg
Zack Heisenberg

Reputation: 519

this might be late reply but i find this bad approach instead of not mounting the app , ( on slow network your user will have a white screen , the app might never mount , so move the logic to App.vue

<template>
  <div v-if="isLoading" class="loading-screen">
    {{ timedout ? "Sorry please check your network" : "Loading..." }}
  </div>
  <div v-else>
    <router-view />
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted } from "vue";
import { useRouter } from "vue-router";
import firebase from "firebase/compat/app";
import "firebase/compat/auth";

import { useAuthStore } from "./stores/user";
const auth = firebase.auth();
const authStore = useAuthStore()

export default defineComponent({
  name: "App",
  setup() {
    const isLoading = ref(true);
    let timedout = ref(false)
    onMounted(() => {
      let timeout = setTimeout(() => {
        timedout.value = true
      }, 5000)
      const router = useRouter();
      const unsubscribe = auth.onAuthStateChanged((user) => {
        clearTimeout(timeout)
        isLoading.value = false;
        if (user) {
          authStore.fbUser = user;
        } else {
          router.push("/auth");
        }
      });
      return () => {
        unsubscribe();
      };
    });

    return {
      isLoading,
      timedout
    };
  },
});
</script>

<style>
.loading-screen {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  color: white;
  background-color: rgb(0, 0, 0);
  font-size: 24px;
}
</style>

Upvotes: 1

Maverick Fabroa
Maverick Fabroa

Reputation: 1173

The Vue 3's createApp is same as Vue 2's new Vue(), returning Vue app instance:

let app;

auth.onAuthStateChanged(() => {
  if (!app) {
    app = createApp(App).use(store).use(router).mount('#app')
  }
})

Upvotes: 7

Related Questions