firebase-module: Nuxt Generate + RealtimeDatabase / Firestore results in "Nuxt Generate finished but did not exit"

When using nuxt generate, the following warning appears at the end (after a successful generate)

Problem

Screenshot 2020-11-08 at 15 19 20
⚠ Nuxt Warning 

The command 'nuxt generate' finished but did not exit after 5s
This is most likely not caused by a bug in Nuxt.js
Make sure to cleanup all timers and listeners you or your plugins/modules start.
Nuxt.js will now force exit

DeprecationWarning: Starting with Nuxt version 3 this will be a fatal error  

Possible Solution

It can theoretically be fixed by calling goOffline() for RealtimeDb or terminate() for Firestore after the generate:done hook.

export default {
  hooks: {
    generate: {
      done(builder) {
        $fireDb.goOffline()
        $fireStore.goOffline()
      }
    }
  },
  • Problem now is: How do we access $fireDb or $fireStore in this hook and how do we implement this in nuxt-firebase?

Might be a big issue when Nuxt v3 arrives.

(Originated from https://github.com/lupas/nuxt-fire/issues/90#issuecomment-590052067)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 4
  • Comments: 26 (11 by maintainers)

Most upvoted comments

Alright guys, so I found a way to make this work without having to create any additional files. Just do the following in your nuxt.config.js:

hooks: {
  generate: {
    async done(builder) {
      const appModule = await import('./.nuxt/firebase/app.js')
      const { session } = await appModule.default(
        builder.options.firebase.config,
        {
          res: null,
        }
      )
      try {
        session.database().goOffline()
      } catch (e) { }
      try {
        session.firestore().terminate()
      } catch (e) { }
    },
  },
},

What I am doing is:

  1. Take the Firebase config out of builder.options.firebase.config
  2. Get the Firebase instance from ./.nuxt/firebase/app.js
  3. Call goOffline() / terminate() on RealtimeDatabase and Firestore through that instance

I assume that with Nuxt 3 the API and possibly the hooks will change quite a bit so that this has to be reevaluated anyway (maybe we can access the context in the hooks then?). Until Nuxt 3 is released (possibly around Q1 2021) this should be a good workaround.

ToDo’s

So a short-term solution I’ve determined from these two posts is:

  1. Move your firebase config to a shared file such as {project_root}/firebase.config.js:
module.exports = {
  apiKey: "...",
  authDomain: "...",
  databaseURL: "...",
  projectId: "...",
  storageBucket: "...",
  messagingSenderId: "...",
  appId: "...",
  measurementId: "..."
}
  1. Create a plugins/firebaseInit.js file:
import firebase from 'firebase/app'
import 'firebase/database'
import 'firebase/firestore'

if (!firebase.apps.length) {
  firebase.initializeApp(require('../firebase.config.js'))
}

export const fireDb = firebase.database()
export const fireStore = firebase.firestore()
  1. Change your nuxt.config.js to import the config file and add a generate.done() hook around the plugin:
import { fireDb, fireStore } from './plugins/firebaseInit.js'

export default {
  // ...
  modules: [
    // ...
    [
      '@nuxtjs/firebase',
      {
        config: require('./firebase.config.js'),
        services: {
          auth: true,
          realtimeDb: true,
          firestore: true,
          // ...
        }
      }
    ]
  ],
  // ...
  hooks: {
    generate: {
      done(builder) {
        try { fireDb.goOffline() } catch (e) { }
        try { fireStore.terminate() } catch (e) { }
      }
    }
  }
}

Added option to automatically terminate databases with v7.5.0, hope that works for everyone!

See documentation: https://firebase.nuxtjs.org/guide/options#terminateDatabasesAfterGenerate

Some further development: Adding the firebase session to the generator object like so:

hooks: {
      generate: {
        async before(generator, generateOptions){
          const appModule = await import('./.nuxt/firebase/app.js')
          const {session} = await appModule.default(
            generator.options.firebase.config,
            {
              res: null,
            }
          )
          generator.firebase = session
}}

from that moment on firebase is accessible in all generate hooks.

    hooks: {
      generate: {
   async done(generator) {
          try {
            generator.firebase.database().goOffline()
          } catch (e) { }
          try {
            generator.firebase.firestore().terminate()
          } catch (e) { }
}

I think this would be a nice addition to the module. adding the firebase instance to the generate property and making it accessible

As I am currently extending routes and providing payloads through the generate hooks, I am using it in multiple hooks. Without the need of seperate imports etc.

Thank you for showing me how to work with hooks!

@mandalornl Not a big fan of adding code “just to be safe”… The import of Firestore & Database should not be needed since we already import them when instantiating them.

Thanks for letting me know about the SIGSEGV error, interesting. It’s working just fine for me. Can you share some details about your environment? Does that error only appear within docker? Which node.js version are you using? Have you tried using a more current version?

It does work for me as well when using require(), so I might change the code to that, but first would like to know what the issue could be.

Thanks for your support!

@mandalornl thanks for posting! Yours is the only one that worked out-of-the-box for me

Yes i posted it as a feature request. nuxt generate doesn’t create the .nuxt folder. Therefore for production i run “nuxt build && nuxt generate” nuxt build creates the .nuxt folder and nuxt generate is smart enough not to re-build again, so no time is lost. https://github.com/nuxt/nuxt.js/issues/8365

I had to import firebase/app instead of ./.nuxt/firebase/app, because the latter could not be found by our docker build server. The following nuxt.config.js example seems to work though.

// nuxt.config.js
export default {
  ssr: true,
  target: 'static',
  modules: [
    '@nuxtjs/firebase'
  ],
  firebase: {
    config: {
      // ...
    },
    services: {
      firestore: true
    }
  },
  hooks: {
    generate: {
      async before(generator) {
        const { default:firebase } = await import('firebase/app');

        await import('firebase/firestore');

        if (!firebase.apps.length) {
          firebase.initializeApp(generator.options.firebase.config);
        }

        generator.firebase = firebase.apps[0];
      },
      done(generator) {
        generator.firebase.firestore().terminate()
          .then(() => console.log('Firestore terminated'))
          .catch(console.error);
      }
    }
  }
}

Fantastic! Works like a charm, this cost me 2 days of hunting and trying. definitely need to learn some more of the indepth nuxt workings. Didnt really know what to do with hooks. (☞゚ヮ゚)☞

Reopened because issue still exists, also see (https://github.com/nuxt-community/firebase-module/issues/373).

Will try to find a solution that does not require a workaround.

I’d like to add that this is still relevant on the new target: static Nuxt functions; nuxt build & nuxt export