Firebase includes a feature called Cloud Firestore, which is their database. A database holds data for your web app and will send it to your app when you need it. Keeping the data separate helps keep everything manageable, flexible, and robust.
Databases often store information that you want to control access to, like people's email addresses or even passwords. Firebase lets you do that with rules.
When you first create your database, by default no one can access anything. This is to make sure you don't accidentally share something you don't want to.
Your database doesn't store anything sensitive yet, so we'll change the rules so that anyone can read or write information to the collections.
allow
line so that it says true
instead of false
.In the previous guide you added the connection to your Firebase project, but now we need to add the actual Firestore database.
import { getFirestore } from 'firebase/firestore'
const db = getFirestore(app)
This constant variable represents the database for the rest of your SvelteKit app.
Adding data to your database is going to require two parts:
The function will live in your db.js
file and save whatever classroom comes to it into the database. It'll save it into the classrooms collection.
You can read all about this in Firebase's excellent documentation.
collection
and addDoc
functions from firestore
. You can put them in the same set of curly brackets that has getFirestore
.// Saves a person object to the database.
export async function addClassroom(classroom) {
const personDoc = await addDoc(collection(db, 'classrooms'), classroom)
}
The interface will be on the main page of your app for now.
addClassroom
function you just created.newClassroom
object with properties for roomNumber
, description
, and numberOfSeats
label
for each of the object's properties and inside each label
bind an input
to the property.button
that sends the newClassroom
object to the addClassroom
function.<script>
import Header from '$lib/Header.svelte'
import Footer from '$lib/Footer.svelte'
import { addClassroom } from '$lib/db.js'
let newClassroom = {
roomNumber: '',
description: '',
numberOfSeats: '',
}
</script>
<Header />
<main class="content section">
<label class="label">
Room number: <input type="number" bind:value={newClassroom.roomNumber} />
</label>
<label class="label">
Description: <input bind:value={newClassroom.description} />
</label>
<label class="label">
Number of seats: <input type="number" bind:value={newClassroom.numberOfSeats} />
</label>
<button class="button" on:click={() => { addClassroom(newClassroom) }}>
Save
</button>
</main>
<Footer />
Getting data from your database is also going to require two parts:
The function will live in your db.js
file and get all the classrooms from the classrooms collection in your database.
getDocs
to your import
from firestore
.getClassrooms
, but also add export
and async
to the start.// Gets all the classrooms from the database.
export async function getClassrooms() {
}
classrooms
.// Gets all the classrooms from the database.
export async function getClassrooms() {
let classroomDocs = await getDocs(collection(db, 'classrooms'))
let classrooms = []
}
// Gets all the classrooms from the database.
export async function getClassrooms() {
let classroomDocs = await getDocs(collection(db, 'classrooms'))
let classrooms = []
classroomDocs.forEach((classroomDoc) => {
classrooms = [...classrooms, classroomDoc.data()]
})
}
classrooms
array back to wherever the function was called from.// Gets all the classrooms from the database.
export async function getClassrooms() {
let classroomDocs = await getDocs(collection(db, 'classrooms'))
let classrooms = []
classroomDocs.forEach((classroomDoc) => {
classrooms = [...classrooms, classroomDoc.data()]
})
return classrooms
}
<script>
import Header from '$lib/Header.svelte'
import Footer from '$lib/Footer.svelte'
import { addClassroom, getClassrooms } from '$lib/db.js'
let classrooms = getClassrooms()
let newClassroom = {
roomNumber: '',
description: '',
numberOfSeats: '',
}
</script>
npm run dev
command in the terminal and open the page in your browser. Make sure you haven't got any errors on the page or in the console.We have an array of classroom
objects, so let's start by putting all their details on the front page.
main
, use the {#await ...}
block to get the page to show that it's loading while we wait for the data from the database to arrive.{#await classrooms}
<p>Loading...</p>
{:then classrooms}
{/await}
classroom
array arrives, we can use an {#each ...}
block to iterate over it.{#await classrooms}
<p>Loading...</p>
{:then classrooms}
{#each classrooms as classroom}
{/each}
{/await}
person
object in any way we want.{#await classrooms}
<p>Loading...</p>
{:then classrooms}
{#each classrooms as classroom}
<p>{classroom.roomNumber} {classroom.description} {classroom.numberOfSeats}</p>
{/each}
{/await}
Well done! You've successfully got the basics of Firebase Firestore by connecting your application to a powerful cloud database, storing your first pieces of information as objects, and bringing all that data back to display on your page. These are foundational skills that open up heaps of possibilities for the applications you're building.
While fetching an entire collection is useful, often you'll want to work with more precision. Imagine needing to:
Beyond these individual operations, you can also start asking more intelligent questions of your database. Think about sorting your retrieved classrooms alphabetically. Firestore allows you to do these things as part of the function in your code, or you can write the JavaScript to do it yourself.
It's important to think about what functionality your project needs. Do you need to edit data? Search for specific items? The official Firebase documentation is an excellent resource, packed with examples. Even if you're not sure how to do it now, as long as you know what you need to do then you'll be able to figure out how to do it by looking at examples, reading the documentation, and helping each other.