How to connect to Firebase in Nuxt3
Guideline on how to connect your firebase DB in Nuxt3
Guideline on how to connect your firebase DB in Nuxt3
Remembers the struggles to find out how to connect Firebase in Nuxt 3 when it was just released. I realized this blog post might be able those who are in search of find a way to connect Firebase in Nuxt 3. In this post, I will go thru with you the steps to connect your Firebase DB in Nuxt 3.
Start off by creating a Nuxt 3 starter project by running the following command.
npx nuxi@latest init <project-name>
npm install firebase
You will need to create .env in your root directory before making the configuration in nuxt.config.ts. runtimeConfig here will allow us to access the variables using the useRunTimeConfig API.
// in nuxt.config.ts
export default defineNuxtConfig({
devtools: { enabled: true },
css: ["~/assets/main.css"],
runtimeConfig: {
public: {
FB_API_KEY: process.env.NUXT_FB_API_KEY,
FB_AUTH_DOMAIN: process.env.NUXT_FB_AUTH_DOMAIN,
FB_PROJECT_ID: process.env.NUXT_FB_PROJECT_ID,
FB_STORAGE_BUCKET: process.env.NUXT_FB_STORAGE_BUCKET,
FB_MESSAGING_SENDER_ID: process.env.NUXT_FB_MESSAGING_SENDER_ID,
FB_APP_ID: process.env.NUXT_FB_APP_ID,
FB_MEASUREMENT_ID: process.env.NUXT_FB_MEASUREMENT_ID,
},
},
});
In order to initialize Firebase, you will need to create a Nuxt plugin in the plugins directory. defineNuxtPLugin is a helper function to define your Nuxt Plugin. This is to make the authentication instance and firestore instance available in Nuxt instance.
useRunTimeConfig is used to access runtime config variables that is setup in nuxt.config.ts.
// in /plugins/firebase.client.ts
import { defineNuxtPlugin, useRuntimeConfig } from "nuxt/app";
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig();
const firebaseConfig = {
apiKey: config.public.FB_API_KEY,
authDomain: config.public.FB_AUTH_DOMAIN,
projectId: config.public.FB_PROJECT_ID,
storageBucket: config.public.FB_STORAGE_BUCKET,
messagingSenderId: config.public.FB_MESSAGING_SENDER_ID,
appId: config.public.FB_APP_ID,
measurementId: config.public.FB_MEASUREMENT_ID,
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const firestore = getFirestore(app);
// need to intentionally return in provide so that it will
// automatically typed safe it for developer
return {
provide: {
auth,
db: firestore,
},
};
});
This is the sample data format used in this project.
// sample data in firestore
{
"name": "Some famouse cereal",
"id": "oiansda0onnad224jnaaso",
"createdAt": {
"seconds": 1694325417,
"nanoseconds": 801000000
}
}
useNuxtApp is a built-in composable that provides a way to access shared runtime context of Nuxt, which is available on both client and server side. It helps you access the Vue app instance, runtime hooks, runtime config variables and internal states, such as ssrContext and payload.
In this case, as you can see db is the firestore instance reference (after the dollar symbol ($)).
// in components/DisplayDocs.vue
<script setup lang="ts">
import { onBeforeMount, ref } from "vue";
import type { Ref } from "vue";
import { useNuxtApp } from "nuxt/app";
//firebase
import { collection, getDocs, Timestamp } from "firebase/firestore";
//lodash
import orderBy from "lodash/orderBy";
//interface
interface Product {
id: string;
name: string;
created_at: Timestamp;
}
//props
//define
const nuxtApp = useNuxtApp();
const values: Ref<Product[]> = ref([]);
//function
const getData = async () => {
try {
const collectionName = collection(nuxtApp.$db, "products");
const data = await getDocs(collectionName);
data.docs.forEach((doc) => {
values.value.push(doc.data() as Product);
});
values.value = orderBy(values.value, ["createdAt"], ["desc"]);
} catch (error) {
console.log(error);
}
};
onBeforeMount(async () => {
await getData();
});
</script>
<template>
<div class="py-7">
<h1 class="text-4xl font-extrabold text-center mb-7">
Firebase Read Collection
</h1>
<ul v-if="values.length > 0" class="flex gap-5 px-10 justify-center">
<li v-for="item in values" class="py-3 px-5 bg-slate-200 rounded-md">
<h2 class="text-2xl font-semibold">{{ item.name }}</h2>
</li>
</ul>
<p v-else class="text-center">Loading...</p>
</div>
</template>
Similar to firestore instance. From here, we can get the authentication instance using useNuxtApp API. auth is the authentication instance reference after the dollar symbol ($).
// in components/Register.vue
<script setup lang="ts">
import { ref } from "vue";
import { useNuxtApp } from "nuxt/app";
//firebase
import { createUserWithEmailAndPassword } from "firebase/auth
//define
const nuxtApp = useNuxtApp();
const email = ref("");
const password = ref("");
const createAccount = async (e: Event) => {
e.preventDefault();
if (!email.value || !password.value) {
return;
}
try {
console.log("creating");
await createUserWithEmailAndPassword(
nuxtApp.$auth,
email.value,
password.value
);
console.log("successfully create an account!");
} catch (error) {
console.error(error);
}
};
</script>
<template>
<form
class="max-w-xl mx-auto py-5 flex flex-col gap-3"
@submit="createAccount"
>
<h1 class="text-4xl font-extrabold text-center mb-3">Register</h1>
<input
type="email"
name="email"
id="email"
placeholder="Email"
autocomplete="off"
required
v-model="email"
/>
<input
type="password"
name="password"
id="password"
placeholder="**********"
required
v-model="password"
/>
<button
type="submit"
class="bg-slate-500 text-white py-2 px-5 rounded-lg cursor-pointer"
>
Register
</button>
</form>
</template>
<style scoped>
input {
@apply border rounded p-2;
}
</style>
// in Login.vue
<script setup lang="ts">
import { ref } from "vue";
//store
import { useNuxtApp } from "nuxt/app";
//firebas
import { signInWithEmailAndPassword } from "firebase/auth";
const nuxtApp = useNuxtApp();
const email = ref("");
const password = ref("");
const signInUser = async (e: Event) => {
e.preventDefault();
if (!email.value || !password.value) {
return;
}
try {
await signInWithEmailAndPassword(
nuxtApp.$auth,
email.value,
password.value
);
console.log("successfully logged in!");
} catch (error) {
console.error(error);
}
};
</script>
<template>
<form class="max-w-xl mx-auto py-5 flex flex-col gap-3" @submit="signInUser">
<h1 class="text-4xl font-extrabold text-center mb-3">Login</h1>
<input
type="email"
name="email"
id="email"
placeholder="Email"
autocomplete="off"
required
v-model="email"
/>
<input
type="password"
name="password"
id="password"
placeholder="**********"
required
v-model="password"
/>
<button
type="submit"
class="bg-slate-500 text-white py-2 px-5 rounded-lg cursor-pointer"
>
Login
</button>
</form>
</template>
<style scoped>
input {
@apply border rounded p-2;
}
</style>
You may find the complete template source code in https://github.com/eazypau/nuxt3-firebase-template.
Check out my portfolio website (https://www.eazypau.com/).