Check Firebase onAuthStateChanged before Vue app created in Nuxt JS

Viewed 1293

I have been using Vue JS v2 for some time now and I'm quite comfortable with it. Recently I have started using Nuxt JS and so far I was able to grasp most of the things. But after spending countless hours of searching the web, I am still unable to find out a way about how to use firebase onAuthStateChanged() before the Vue app gets created in Nuxt JS.

Let me explain a bit

In Vue 2 normally what I do is in main.js file

import Vue from 'vue' 
import App from './App.vue'
import { auth } from '@/firebase/init'

let app = null

// ⚡ Wait for firebase auth to init before creating the Vue app
auth.onAuthStateChanged(() => {
  // init app if not already created
  if (!app) {
    app = new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
  }
})

But in Nuxt JS the entire main.js file is encapsulated. Now I know that I can use plugin to do stuff like Vue.use() but again those things are happening after the Vue app is created.

I want to wrap the vue app creation inside the firebase auth checking so I see no way to implement this. So, if anyone has any idea about how to implement this then please let me know.

Please note that I am not trying to do any redirection based on the auth state. I know those answers already exist here and I have checked them already.

2 Answers

I had the same problem and found an easier solution. However, I don't why this is not documented anywhere in firebase nuxt...

In the layouts/default.vue Layout I implemented the following:

<template>
  <div>
    <div v-show="!isLoaded" class="loading">
    </div>
    <div class="app" id="app" v-if="loaded">
      <NavBar :loggedIn="loggedIn" />
      <Nuxt id="router-view" />
      <Footer />
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        loggedIn: false,
        loaded: false
      }
    },
    created() {
      this.$fire.auth.onAuthStateChanged(() => {
        this.loaded = true
        const user = this.$fire.auth.currentUser;
        if (user) {
          this.loggedIn = true
        }
      })
    },
    ...
  }
</script>

I think this works exactly like using it in the main.js in vueJS. By using v-if the main app content should only be executed once firebase auth is initialised.

I guess I have a similar problem and I managed to create a login-flow, but it feels like a workaround.

on login I store cookie and user data:

  1. after login via firenbase I save userdata from authUser in vuex store via the onAuthStateChanged hook, which resides in a clientside only plugin.
  2. store firebase token as cookie

on pageReload:

  1. init store on serverside with data from cookie, with nuxtServerInit: https://github.com/davidroyer/nuxt-ssr-firebase-auth.v2/blob/master/store/index.js
  2. onAuthStateChanged is triggered and does nothing, because the userStore is already initialised

on redirect into app:

  1. if user comes back into my app from payment service provider for example, the vuex store is empty until firebaseAuth plugin loads and saves userdata in vuex store. I use localStorage to persist the public user here, so the app thinks we are still logged in. https://www.npmjs.com/package/nuxt-vuex-localstorage

  2. In the background onAuthStateChanged is triggered. This feels wrong.

Especially in the "on redirect into app" case it would be nice if onAuthStateChanged is handled first, because then we could skip localStorage and use access userData from firestore fore example without having to wait for the authPlugin to come up.

Maybe a solution could be to write a module, which offers more hooks you can use: https://nuxtjs.org/guide/modules/#run-tasks-on-specific-hooks

Related