Hopp til innhold

Fagstoff

Skrive data til Cloud Firestore

I NoSQL-databaser organiseres data i samlinger som består av flere dokumenter. I denne artikkelen skal du lære to metoder for å opprette dokumenter i Cloud Firestore.
En modell av en sky foran to liggende ringpermer fulle av papir. Foto.
Åpne bilde i et nytt vindu

Forskjellen på relasjonsdatabaser og dokumentbaserte databaser

Tidligere har du kanskje lært å modellere relasjonsdatabaser og å kode dem i SQL. En viktig forskjell på relasjonsdatabaser (SQL-baserte databaser) og dokumentbaserte databaser (NoSQL-databaser) er at i dokumentbaserte databaser er det ingen forhåndsbestemte regler for hvordan databasen skal bygges opp. Hele databasen tar utgangspunkt i ei tekstfil (ofte ei .JSON-fil) der vi legger all dataene inn, uten å ha bestemt felt, rader og kolonner på forhånd. Vi skriver rett og slett bare all dataene inn i tekstfila. Dette gjør dokumentbaserte databaser veldig fleksible og enkle å sette opp, men det krever også mer orden fra dem som skal bruke databasen. For at en slik database skal være brukervennlig, krever det dessuten at programmet eller nettsiden vi bruker til å få tilgang til databasen, er satt opp på en måte som gjør det enklere å legge inn riktig data.

Vi kan likevel trekke ut noen likheter mellom relasjonsdatabaser (SQL) og dokumentbaserte databaser (NoSQL). En tabell i SQL tilsvarer ei samling (collection) i NoSQL, og en rad (all dataene tilknyttet et objekt i databasen) i SQL tilsvarer et dokument (document) i NoSQL. Du kan lese mer om oppbyggingen av dokumentbaserte databaser på MongoDBs side "What is a Document Database".

Trenger vi datamodellering med dokumentbaserte databaser?

En datamodell med seks firkanter. Noen av firkantene er koblet sammen med andre med linjer. Linjene har streker eller piler på endene. Inne i firkantene er det linjer som representerer tekst. Øverste tekstlinje i hver firkant har et nøkkelikon foran seg. Illustrasjon.

Det kan kanskje være enkelt å tro at vi ikke trenger datamodellering i NoSQL-databaser, siden vi ikke trenger å opprette tabeller og felt på samme måte som i SQL, men det kan uansett være en god idé å ha oversikt over hvordan dataene skal organiseres i databasen. Derfor kan det være lurt å sette opp en datamodell også når du skal bruke NoSQL-databaser.

På bildet under ser du oppbyggingen av en Firestore-database med elevdata:

Modell av dokumentdatabase. Ei liste med ID-koder peker mot dokumenter med informasjon om forskjellige personer. Illustrasjon.

Som du kan se på bildene, har noen av elevene ulik info. Noen har telefon, andre har e-post, og noen har begge deler. Dette ville ikke ha vært mulig i en SQL-database, der alle feltene må være opprettet på forhånd. Dette viser noe av fleksibiliteten i en NoSQL-database.

Legge inn data i databasen

Du skal nå legge inn dataene fra bildet over i Firebase-databasen din. Åpne HTML-fila index.html som du opprettet i forrige leksjon. Scriptet i index.html skal se omtrent slik ut:

Firebase-konfigurasjon

1<script type="module">
2  // Importerer intitalizApp fra Firebase-app SDK
3  import { initializeApp } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-app.js";
4  // Importerer alle Firestore-funksjonene vi skal bruke 
5  // Om du får feilmeldinga "ReferenceError: [...] is not defined", kan det være det fordi du har brukt en Firestore-funksjon uten å ha importert den her.
6  import { getFirestore } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-firestore.js"
7
8  // Konfigurerer Firebase
9  const firebaseConfig = {
10    apiKey: "_API_KEY_",
11    authDomain: "_PROJECT_ID_.firebaseapp.com",
12    projectId: "_PROJECT_ID_",
13    storageBucket: "_PROJECT_ID_.appspot.com",
14    messagingSenderId: "_SENDER_ID_",
15    appId: "_APP_ID_",
16  };
17
18  // Starter opp Firebase med den angitte konfigurasjonen
19  const app = initializeApp(firebaseConfig);
20  // Henter ut referanse til Firestore-databasen
21  const db = getFirestore();
22</script>

Opprette et nytt dokument i databasen

Du skal nå skrive kode for å opprette et nytt dokument i databasen. Den enkleste måten å gjøre dette på er å bruke Firestore-funksjonene addDoc() og collection(). Dokumenter som opprettes med addDoc() får automatisk en unik ID, så du trenger ikke tenke på at dokumentet må ha en primærnøkkel.

En viktig ting med funksjonene som er knyttet til Firestore, er at de er asynkrone. Det vil si at når en databaseoperasjon skal kjøre, vil programmet fortsette å kjøre neste kodelinje uten å vente på at kommunikasjonen med databasen er fullført. Derfor skriver vi ordet await foran disse funksjonene, slik at programmet venter til kommunikasjonen med databasen er fullført før neste kodelinje kjøres.

addDoc() er en funksjon for å skrive data til databasen. Denne funksjonen tar inn to parametere: hvilken samling (collection) dataene skal skrives til, og hvilken data som skal skrives, slik:

addDoc(_COLLECTION_, _DATA_);

Dataene skrives inn på formen

{

_FELTNAVN_1_: "_DATA_1_",

_FELTNAVN_2_: "_DATA_2_"

}

collection() brukes inne i addDoc() for å angi hvilken database som skal brukes, og hvilken samling (collection) inne i databasen dataene skal skrives til. En samling i dokumentbaserte databaser tilsvarer som sagt omtrent en tabell i relasjonsdatabaser, og et dokument tilsvarer en rad. Koden for å lage en referanse til en elev blir derfor slik:

collection(_DATABASE_, "_NAVN_PÅ_COLLECTION_");

Husk å importere Firebase-funksjonene

Alle funksjonene du bruker som er spesielle for Firebase, og ikke generelle JavaScript-funksjoner, må importeres. Vi har allerede importert initializeApp fra (...)/firebase-app.js og getFirestore fra (...)/firebase-firestore.js i koden over. Når vi skal skrive kode videre, må vi huske å importere alle funksjoner vi ikke har brukt før fra (...)/firebase-firestore.js. For å bruke addDoc() og collection() må vi derfor legge dem inn i import-setningen over, rett etter import { getFirestore, slik:

import { getFirestore, addDoc, collection } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-firestore.js"

Foran hvert kodeeksempel videre i teksten er det lagt inn en kommentar med hvilke funksjoner som må importeres for at koden skal fungere.

Legge inn en elev i databasen

Nå er du klar til å legge inn den første eleven i databasen. Skriv koden under nederst i scriptet ditt. Husk å skrive await foran funksjonen som starter kommunikasjon med databasen.

Lag nytt dokument med autogenerert ID

1// import { addDoc, collection } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-firestore.js";
2
3// Lager et nytt dokument i samlinga "elever"
4await addDoc(
5  collection(db, "elever"), {
6    fornavn: "Rebecca",
7    etternavn: "Thomasen",
8    telefon: "12345678"
9});

Lagre HTML-dokumentet og åpne det i en nettleser. Åpne inspiser-verktøyet for å sjekke at du ikke har noen feilmeldinger i konsollen, og se på Firestore-databasen din. Nå skal du finne et nytt dokument med dataene du la inn.

Database i Cloud Firestore. Tre felt: et med overskriften "elevliste", et med overskriften "elever" og et der man får opp navnet og telefonnummeret til eleven Rebecca Thomasen. Skjermbilde.

Opprette et nytt dokument i databasen med egendefinert ID

setDoc() er en annen måte å opprette nye dokumenter i databasen på. setDoc() gir deg muligheten til å definere en egen primærnøkkel for hvert dokument i databasen, slik at du kan bruke for eksempel brukernavn, e-post eller en egendefinert ID (elev-ID, kundenummer) som primærnøkkel. setDoc() brukes i kombinasjon med doc() for å angi hvor dokumentet skal lagres i databasen, og hva som skal være primærnøkkelen.

setDoc() er en funksjon for å skrive data til en spesifikk ID i databasen. Denne funksjonen tar inn to parametere: hvilket dokument dataene skal skrives til (angitt med ID), og hvilken data som skal skrives, slik:

setDoc(_DOCUMENT_, _DATA_);

Dataene skrives inn på formen

{

_FELTNAVN_1_: "_DATA_1_",

_FELTNAVN_2_: "_DATA_2_"

}

doc() brukes inne i setDoc(), for å angi hvilken database som skal brukes, hvilken samling (collection) inne i databasen dataene skal skrives til, og hvilken ID dokumentet skal ha. Koden for å lage en referanse til en elev blir derfor slik:

doc(_DATABASE_, "_NAVN_PÅ_COLLECTION_", "_ID_");

Merk at ID-en alltid må være definert som tekst, med anførselstegn. Hvis du ønsker å bruke nummer som ID, må du derfor også skrive tallet i anførselstegn, slik: "3".

Legge inn en elev i databasen

Nå er du klar til å legge inn en ny elev med egendefinert ID i databasen. Som ID velger vi å lage et brukernavn med de første bokstavene i etternavnet og de to første bokstavene i fornavnet. Importer funksjonene setDoc og doc fra (...)/firebase-firestore.js, og skriv koden under nederst i scriptet ditt. Husk å skrive await foran funksjonen som starter kommunikasjon med databasen.

Lag nytt dokument med egendefinert ID

1// import { setDoc, doc } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-firestore.js";
2
3// Lager et nytt dokument i samlinga "elever"
4await setDoc(
5  doc(db, "elever", "nilja"), {
6    fornavn: "Jakob",
7    etternavn: "Nilsen",
8    epost: "jakob@nilsen.net"
9  });

Lagre HTML-dokumentet og åpne det i en nettleser. Åpne inspiser-verktøyet for å sjekke at du ikke har noen feilmeldinger i konsollen, og se på Firestore-databasen din. Nå skal du finne et nytt dokument med dataene du la inn. Legg merke til at ID-en til dokumentet er det samme som vi anga i koden ("nilja").

Database i Cloud Firestore. Tre felt: et med overskriften "elevliste", et med overskriften "elever", der brukernavnet nilja ligger, og et med overskriften "nilja" der man får opp navnet og e-posten til eleven Jakob Nilsen. Skjermbilde.

Endre et dokument i databasen

Hvis du trenger å endre data i et dokument som allerede er lagret i databasen, kan du bruke funksjonen updateDoc(). Med updateDoc() kan du endre innholdet i felt i et dokument, eller du kan legge til nye felt. updateDoc() har samme syntaks (skrivemåte) som setDoc():

updateDoc(_DOCUMENT_, _DATA_);

Som med setDoc() bruker vi doc() for å hente ut dokumentet:

updateDoc(doc(_DATABASE_, "_COLLECTION_", "_ID_"), { _FELTNAVN_: "_DATA_" });

Vi kan for eksempel endre etternavn og legge til telefonnummer til eleven Jakob Nilsen, som vi nettopp la til. Importer først funksjonen updateDoc fra (...)/firebase-firestore.js, og skriv følgende kode nederst i scriptet ditt:

Endre dokument

1// import { updateDoc, doc } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-firestore.js";
2
3// Endrer feltet "etternavn" i dokumentet og legger til feltet "telefon"
4await updateDoc(
5  doc(db, "elever", "nilja"), {
6    etternavn: "Nilssen",
7    telefon: "2233445"
8});
Databasen i Firebase Cloud Firestore viser at etternavnet er endret til Nilssen med to S-er, mens e-posten har Nilsen med bare en S. Skjermbilde.

Vi har nå endret etternavnet fra Nilsen (én S) til Nilssen (to S-er) og lagt til et telefonnummer. Alle andre felt forblir uendret.

Slette et felt

Vi kan også bruke updateDoc() for å slette felt. Vi må da bruke funksjonen deleteField() inne i updateDoc(), slik:

feltnavn: deleteField()

Vi kan se i databasen at e-posten til Jakob Nilssen fortsatt er med en S, så den er sannsynligvis feil. For å slette e-posten skriver du koden under. Husk å importere deleteField().

Slette et felt

1// import { updateDoc, doc, deleteField } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-firestore.js";
2
3// Sletter feltet "epost" fra dokumentet
4await updateDoc(
5  doc(db, "elever", "nilja"), {
6    epost: deleteField()
7});

Da vil hele e-postfeltet i dokumentet slettes.

Slette et dokument

For å slette et helt dokument kan du bruke funksjonen deleteDoc(). Denne funksjonen har ganske lik skrivemåte som setDoc() og updateDoc(), men her trenger du ikke å angi noen felt siden alle skal slettes. For å slette et dokument trenger du å vite ID-en til dokumentet. For å slette eleven Jakob Nilssen fra databasen skriver du koden under. Husk å importere deleteDoc()).

Slette et dokument

1// import { deleteDoc, doc } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-firestore.js";
2
3// Sletter dokumentet med ID-en "nilja"
4await deleteDoc(
5  doc(db, "elever", "nilja")
6);

Dokumentet er nå slettet fra databasen.

Relatert innhold

I denne guiden vil du lære et basisoppsett som du skal bruke videre i modulen "Lage en dynamisk webside med databasekobling i Firebase Cloud Firestore".

Når vi skal hente data fra Cloud Firestore, kan vi hente ut ett enkelt dokument, alle dokumentene i ei samling, eller vi kan hente data med spørringer.

CC BY-SASkrevet av Karl Arne Dalsaune.
Sist faglig oppdatert 30.05.2022

Læringsressurser

Dynamiske nettsider med NoSQL-databaser