Hopp til innhald
Fagartikkel

Skrive data til Cloud Firestore

I NoSQL-databasar blir data organiserte i samlingar som består av fleire dokument. I denne artikkelen skal du lære to metodar for å opprette dokument i Cloud Firestore.

Forskjellen på relasjonsdatabasar og dokumentbaserte databasar

Tidlegare har du kanskje lært å modellere relasjonsdatabasar og å kode dei i SQL. Ein viktig forskjell på relasjonsdatabasar (SQL-baserte databasar) og dokumentbaserte databasar (NoSQL-databasar) er at i dokumentbaserte databasar er det ingen førehandsbestemde reglar for korleis databasen skal byggast opp. Heile databasen tek utgangspunkt i ei tekstfil (ofte ei .JSON-fil) der vi legg alle dataa inn, utan å ha bestemt felt, rader og kolonnar på førehand. Vi skriv rett og slett berre all dataa inn i tekstfila. Dette gjer dokumentbaserte databasar veldig fleksible og enkle å setje opp, men det krev òg meir orden frå dei som skal bruke databasen. For at ein slik database skal vere brukarvennleg, krev det dessutan at programmet eller nettsida vi bruker til å få tilgang til databasen, er sett opp på ein måte som gjer det enklare å legge inn rett data.

Vi kan likevel trekke ut nokre likskapar mellom relasjonsdatabasar (SQL) og dokumentbaserte databasar (NoSQL). Ein tabell i SQL svarer til ei samling (collection) i NoSQL, og ei rad (alle dataa knytte til eit objekt i databasen) i SQL svarer til eit dokument (document) i NoSQL. Du kan lese meir om oppbygginga av dokumentbaserte databasar på MongoDBs side "What is a Document Database".

Treng vi datamodellering med dokumentbaserte databasar?

Det kan kanskje vere lett å tru at vi ikkje treng datamodellering i NoSQL-databasar, sidan vi ikkje treng å opprette tabellar og felt på same måte som i SQL, men det kan uansett vere ein god idé å ha oversikt over korleis dataa skal organiserast i databasen. Derfor kan det vere lurt å setje opp ein datamodell òg når du skal bruke NoSQL-databasar.

På biletet under ser du oppbygginga av ein Firestore-database med elevdata:

Som du kan sjå på bileta, har nokre av elevane ulik info. Nokre har telefon, andre har e-post, og nokre har begge delar. Dette ville ikkje ha vore mogleg i ein SQL-database, der alle felta må vere oppretta på førehand. Dette viser noko av fleksibiliteten i ein NoSQL-database.

Legge inn data i databasen

Du skal no legge inn dataa frå biletet over i Firebase-databasen din. Opne HTML-fila index.html som du oppretta i førre leksjon. Scriptet i index.html skal sjå omtrent slik ut:

Firebase-konfigurasjon
1<script type="module">
2  // Importerer intitalizApp frå Firebase-app SDK
3  import { initializeApp } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-app.js";
4  // Importerer alle Firestore-funksjonane vi skal bruke 
5  // Om du får feilmeldinga "ReferenceError: [...] is not defined", kan det vere det fordi du har brukt ein Firestore-funksjon utan å ha importert han 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    messagingSendarId: "_SENDAR_ID_",
15    appId: "_APP_ID_",
16  };
17
18  // Startar opp Firebase med den angitte konfigurasjonen
19  const app = initializeApp(firebaseConfig);
20  // Hentar ut referanse til Firestore-databasen
21  const db = getFirestore();
22</script>

Opprette eit nytt dokument i databasen

Du skal no skrive kode for å opprette eit nytt dokument i databasen. Den enklaste måten å gjere dette på er å bruke Firestore-funksjonane addDoc() og collection(). Dokument som blir oppretta med addDoc() får automatisk ein unik ID, så du treng ikkje tenke på at dokumentet må ha ein primærnøkkel.

Ein viktig ting med funksjonane som er knytte til Firestore, er at dei er asynkrone. Det vil seie at når ein databaseoperasjon skal køyre, vil programmet halde fram med å køyre neste kodelinje utan å vente på at kommunikasjonen med databasen er fullført. Derfor skriv vi ordet await framfor desse funksjonane, slik at programmet ventar til kommunikasjonen med databasen er fullført før neste kodelinje blir køyrd.

addDoc() er ein funksjon for å skrive data til databasen. Denne funksjonen tek inn to parametrar: kva samling (collection) dataa skal skrivast til, og kva data som skal skrivast, slik:

addDoc(_COLLECTION_, _DATA_);

Dataa blir skrivne inn på forma

{

_FELTNAMN_1_: "_DATA_1_",

_FELTNAMN_2_: "_DATA_2_"

}

collection() blir brukt inne i addDoc() for å angi kva database som skal brukast, og kva samling (collection) inne i databasen dataa skal skrivast til. Ei samling i dokumentbaserte databasar tilsvarer som sagt omtrent ein tabell i relasjonsdatabasar, og eit dokument svarer til ei rad. Koden for å lage ein referanse til ein elev blir derfor slik:

collection(_DATABASE_, "_NAMN_PÅ_COLLECTION_");

Hugs å importere Firebase-funksjonane

Alle funksjonane du bruker som er spesielle for Firebase, og ikkje generelle JavaScript-funksjonar, må importerast. Vi har allereie importert initializeApp frå (...)/firebase-app.js og getFirestore frå (...)/firebase-firestore.js i koden over. Når vi skal skrive kode vidare, må vi hugse å importere alle funksjonar vi ikkje har brukt før frå (...)/firebase-firestore.js. For å bruke addDoc() og collection() må vi derfor legge dei inn i import-setninga over, rett etter import { getFirestore, slik:

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

Framfor kvart kodedøme vidare i teksten er det lagt inn ein kommentar med kva funksjonar som må importerast for at koden skal fungere.

Legge inn ein elev i databasen

No er du klar til å legge inn den første eleven i databasen. Skriv koden under nedst i scriptet ditt. Hugs å skrive await framfor funksjonen som startar 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// Lagar eit nytt dokument i samlinga "elevar"
4await addDoc(
5  collection(db, "elevar"), {
6    fornamn: "Rebecca",
7    etternamn: "Thomasen",
8    telefon: "12345678"
9});

Lagre HTML-dokumentet og opn det i ein nettlesar. Opne inspiser-verktøyet for å sjekke at du ikkje har nokon feilmeldingar i konsollen, og sjå på Firestore-databasen din. No skal du finne eit nytt dokument med dataa du la inn.

Opprette eit nytt dokument i databasen med eigendefinert ID

setDoc() er ein annan måte å opprette nye dokument i databasen på. setDoc() gir deg moglegheita til å definere ein eigen primærnøkkel for kvart dokument i databasen, slik at du kan bruke til dømes brukarnamn, e-post eller ein eigendefinert ID (elev-ID, kundenummer) som primærnøkkel. setDoc() blir brukt i kombinasjon med doc() for å angi kvar dokumentet skal lagrast i databasen, og kva som skal vere primærnøkkelen.

setDoc() er ein funksjon for å skrive data til ein spesifikk ID i databasen. Denne funksjonen tek inn to parametrar: kva dokument dataa skal skrivast til (angitt med ID), og kva data som skal skrivast, slik:

setDoc(_DOCUMENT_, _DATA_);

Dataa blir skrivne inn på forma

{

_FELTNAMN_1_: "_DATA_1_",

_FELTNAMN_2_: "_DATA_2_"

}

doc() blir brukt inne i setDoc(), for å angi kva database som skal brukast, kva samling (collection) inne i databasen dataa skal skrivast til, og kva ID dokumentet skal ha. Koden for å lage ein referanse til ein elev blir derfor slik:

doc(_DATABASE_, "_NAMN_pÅ_COLLECTION_", "_iD_");

Merk at ID-en alltid må vere definert som tekst, med hermeteikn. Dersom du ønsker å bruke nummer som ID, må du derfor òg skrive talet i hermeteikn, slik: "3".

Legge inn ein elev i databasen

No er du klar til å legge inn ein ny elev med eigendefinert ID i databasen. Som ID vel vi å lage eit brukarnamn med dei første bokstavane i etternamnet og dei to første bokstavane i fornamnet. Importer funksjonane setDoc og doc frå (...)/firebase-firestore.js, og skriv koden under nedst i scriptet ditt. Hugs å skrive await framfor funksjonen som startar kommunikasjon med databasen.

Lag nytt dokument med eigendefinert ID
1// import { setDoc, doc } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-firestore.js";
2
3// Lagar eit nytt dokument i samlinga "elevar"
4await setDoc(
5  doc(db, "elevar", "nilja"), {
6    fornamn: "Jakob",
7    etternamn: "Nilsen",
8    epost: "jakob@nilsen.net"
9  });

Lagre HTML-dokumentet og opne det i ein nettlesar. Opne inspiser-verktøyet for å sjekke at du ikkje har nokon feilmeldingar i konsollen, og sjå på Firestore-databasen din. No skal du finne eit nytt dokument med dataa du la inn. Legg merke til at ID-en til dokumentet er det same som vi skreiv i koden ("nilja").

Endre eit dokument i databasen

Dersom du treng å endre data i eit dokument som allereie er lagra i databasen, kan du bruke funksjonen updateDoc(). Med updateDoc() kan du endre innhaldet i felt i eit dokument, eller du kan legge til nye felt. updateDoc() har same syntaks (skrivemåte) som setDoc():

updateDoc(_DOCUMENT_, _DATA_);

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

updateDoc(doc(_DATABASE_, "_COLLECTION_", "_iD_"), { _FELTNAMN_: "_DATA_" });

Vi kan til dømes endre etternamn og legge til telefonnummer til eleven Jakob Nilsen, som vi nettopp la til. Importer først funksjonen updateDoc frå (...)/firebase-firestore.js, og skriv koden under nedst i scriptet ditt.

Endre dokument
1// import { updateDoc, doc } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-firestore.js";
2
3// Endrar feltet "etternamn" i dokumentet og legg til feltet "telefon"
4await updateDoc(
5  doc(db, "elevar", "nilja"), {
6    etternamn: "Nilssen",
7    telefon: "2233445"
8});

Vi har no endra etternamnet frå Nilsen (éin S) til Nilssen (to S-ar) og lagt til eit telefonnummer. Alle andre felt blir ståande uendra.

Slette eit felt

Vi kan òg bruke updateDoc() for å slette felt. Vi må då bruke funksjonen deleteField() inne i updateDoc(), slik:

feltnamn: deleteField()

Vi kan sjå i databasen at e-posten til Jakob Nilssen framleis er med ein S, så det er sannsynlegvis feil. For å slette e-posten skriv du koden under. Hugs å importere deleteField().

Slette eit felt
1// import { updateDoc, doc, deleteField } from "https://www.gstatic.com/firebasejs/9.6.3/firebase-firestore.js";
2
3// Slettar feltet "epost" frå dokumentet
4await updateDoc(
5  doc(db, "elevar", "nilja"), {
6    epost: deleteField()
7});

Då vil heile e-postfeltet i dokumentet slettast.

Slette eit dokument

For å slette eit heilt dokument kan du bruke funksjonen deleteDoc(). Denne funksjonen har ganske lik skrivemåte som setDoc() og updateDoc(), men her treng du ikkje å angi nokon felt sidan alle skal slettast. For å slette eit dokument treng du å vite ID-en til dokumentet. For å slette eleven Jakob Nilssen frå databasen skriv du koden under. Hugs å importere deleteDoc()).

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

Dokumentet er no sletta frå databasen.

Relatert innhald

Fagstoff
Oppsett av Firebase og Cloud Firestore

I denne guiden vil du lære eit basisoppsett som du skal bruke vidare i modulen "Lage ei dynamisk webside med databasekopling i Firebase Cloud Firestore".

Fagstoff
Lese data frå Cloud Firestore

Når vi skal hente data frå Cloud Firestore, kan vi hente ut eitt enkelt dokument, alle dokumenta i ei samling, eller vi kan hente data med spørjingar.