skip to Main Content

In my project under plugins dir I have a single plugins called firebase.ts and it’s look like this

import { defineNuxtPlugin } from "#app";
import { firebaseConfig } from "@/firebaseConfig";
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";

export default defineNuxtPlugin((nuxtApp) => {
  // Initialize Firebase
  const firebaseApp = initializeApp(firebaseConfig);
  const firebaseAuthInstance = getAuth(firebaseApp);
})

Whenever I run my project it’s give this kind of error. But if I make the plugin client only i mean firebase.client.ts then it work just fine. But I want to get this pluin both in client and server side. How to achive that?

[h3] [unhandled] H3Error: Component auth has not been registered yet
    at createError (file:///home/riyad/Desktop/nuxt-test/node_modules/h3/dist/index.mjs:238:15)
    at Server.nodeHandler (file:///home/riyad/Desktop/nuxt-test/node_modules/h3/dist/index.mjs:428:21) {
  statusCode: 500,
  fatal: false,
  unhandled: true,
  statusMessage: 'Internal Server Error'
}
[nuxt] [request error] Component auth has not been registered yet
  at createError (./node_modules/h3/dist/index.mjs:238:15)  
  at Server.nodeHandler (./node_modules/h3/dist/index.mjs:428:21)

2

Answers


  1. After many attempts, I was able to solve the issue. Here is the code on the directory /plugins/plugins.ts:

    import { getAuth } from "@firebase/auth";
    import { initializeApp } from "firebase/app";
    import { firebaseConfig } from "./firebase/firebaseConfig";
    
    const authInstance = () => {
        const app = initializeApp(firebaseConfig);
        const auth = getAuth(app);
        return auth
    };
    
    export default defineNuxtPlugin(() => {
        return {
            provide: {
                authInstance,
            },
        };
    });
    

    It appears that the initializeApp Function was not called correctly. But if you call the initializeApp and getAuth on a new function it returns The Auth Object correctly.

    Login or Signup to reply.
  2. Firebase libraries use browser cache to store data on client side, so you cannot load some of their libraries on server side. Auth library is used and works only on client site, same as all lib’s with no /lite end. To be able to use library Firestore on server, import all functions from 'firebase/firestore/lite' file path.

    Example of plugin:

    import { defineNuxtPlugin } from '#app'
    import { initializeApp, getApps } from 'firebase/app'
    import { connectFirestoreEmulator as connectFirestoreEmulatorServer, getFirestore as getFirestoreServer } from 'firebase/firestore/lite'
    
    import { connectAuthEmulator, getAuth } from "firebase/auth"
    import { connectDatabaseEmulator, getDatabase } from "firebase/database"
    import { connectFirestoreEmulator, getFirestore } from "firebase/firestore"
    import { connectFunctionsEmulator, getFunctions } from "firebase/functions"
    import { connectStorageEmulator, getStorage } from "firebase/storage"
    
    export default defineNuxtPlugin((nuxtApp) => {
    
      const firebaseConfig = { ...useRuntimeConfig().public.firebaseConfig }
    
      if (!getApps().length) initializeApp(firebaseConfig)
    
      // Code bellow allows to work with local emulators you can delete it if you work without emulators
      if(!process.dev) return
    
      const firestoreHost = getFirestoreServer().toJSON()['settings'].host
    
      if(firestoreHost !== 'localhost:8080') {
        connectFirestoreEmulatorServer(getFirestoreServer(), 'localhost', 8080)
      }
    
      if (process.client) {
        connectAuthEmulator(getAuth(), "http://localhost:9099")
        connectFirestoreEmulator(getFirestore(), "localhost", 8080)
        connectDatabaseEmulator(getDatabase(), "localhost", 9000)
        connectStorageEmulator(getStorage(), "localhost", 9199)
        connectFunctionsEmulator(getFunctions(), "localhost", 5001)
      }
      
    })
    

    Usage:

    <template>
      <div>
        <button @click="signIn">Sign In</button>
        <p>{{ data.test.title }}</p>
        <p>User email: {{userEmail}}</p>
      </div>
    </template>
    
    <script setup lang="ts">
    import { getAuth, OAuthProvider, signInWithPopup } from 'firebase/auth';
    import { doc, getDoc, getFirestore } from 'firebase/firestore/lite';
    
    const data = reactive({ test: null })
    const userEmail = ref('')
    
    const result = await getDoc(doc(getFirestore(), 'test/test'))
    if (result.exists()) data.test = result.data()
    
    // Here example how you can run code only on client.
    // There is `process.server` too.
    if (process.client) {
      const userCredentials = await signInWithPopup(getAuth(), new OAuthProvider('google.com'))
      if (userCredentials.user) userEmail.value = userCredentials.user.email
    }
    
    async function signIn() {
      const userCredentials = await signInWithPopup(getAuth(), new OAuthProvider('google.com'))
      if (userCredentials.user) userEmail.value = userCredentials.user.email
    }
    </script>
    

    Code directly in setup will run on server and client. Function signIn and if (process.client) will run only on client same as life cycle hooks like onMounted()

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search