React Native Academy · Lektion

Læsning og skrivning af Firestore-dokumenter

Tilføj, læs, opdatér og slet dokumenter i en Firestore-samling ved hjælp af Firestore-modulet, strukturér data med undersamlinger, og anvend sikkerhedsregler.

Lektion 3 af 413 trin

Læsning og skrivning af Firestore-dokumenter er en gratis React Native Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i React Native Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. React Native Academy-kurset indeholder 4 lektioner i alt.

Firestores datamodel

Cloud Firestore er en NoSQL-dokumentdatabase. Data organiseres i samlinger (som mapper), der indeholder dokumenter (som JSON-filer). Hvert dokument har et unikt ID og et sæt felter med nøgler og værdier. Dokumenter kan indeholde undersamlinger til indlejrede data.

En posts-samling kan for eksempel indeholde mange indlægsdokumenter, hver med felter som title, content og userId. Et indlægsdokument kan have en indlejret comments-undersamling til svarene. Denne model skalerer anderledes end SQL — tænk først på adgangsmønstrene, og modeller derefter dataene i overensstemmelse med dem.

Hentning af en samlingsreference

Få adgang til en Firestore-samling ved hjælp af firestore().collection('collection-name'). Dette returnerer en CollectionReference, som du bruger til at læse dokumenter, tilføje nye dokumenter eller lytte efter ændringer. Samlingsreferencer er lette og udløser ikke selv netværkskald.

Hvis du vil referere til et bestemt dokument i en samling, skal du kæde .doc('document-id') på. Hvis du vil have Firestore til at generere et tilfældigt ID, skal du udelade argumentet, når du opretter et nyt dokument med .add().

import firestore from '@react-native-firebase/firestore';

// Reference to the 'posts' collection
const postsRef = firestore().collection('posts');

// Reference to a specific post document
const postRef = firestore().collection('posts').doc('post-id-123');

// Reference to a sub-collection
const commentsRef = firestore()
  .collection('posts')
  .doc('post-id-123')
  .collection('comments');

Tilføjelse af et dokument

Brug .add(data) på en samlingsreference til at oprette et nyt dokument med et af Firestore genereret ID. Brug .doc(id).set(data) til at oprette eller overskrive et dokument med et bestemt ID.

Hjælpefunktionen firestore.FieldValue.serverTimestamp() angiver et tidsstempel på serversiden, så alle klienter ser det samme oprettelsestidspunkt uanset forskelle i enhedens ur. Brug altid tidsstempler fra serveren til felterne createdAt og updatedAt.

// Add with auto-generated ID
const newPost = await firestore().collection('posts').add({
  title: 'Hello Firestore',
  content: 'My first post!',
  userId: auth().currentUser?.uid,
  createdAt: firestore.FieldValue.serverTimestamp(),
});
console.log('New post ID:', newPost.id);

// Set with specific ID
await firestore().collection('users').doc(userId).set({
  displayName: 'Alice',
  email: 'alice@example.com',
  createdAt: firestore.FieldValue.serverTimestamp(),
});

Læsning af et enkelt dokument

Kald .get() på en DocumentReference for at hente dokumentet én gang. Resultatet er et DocumentSnapshot. Kontrollér snapshot.exists, før du læser data — hvis dokumentet aldrig er blevet oprettet, er exists false, og snapshot.data() returnerer undefined.

Metoden snapshot.data() returnerer et almindeligt JavaScript-objekt med alle dokumentets felter. Dokumentets ID tilgås via snapshot.id, ikke via dataobjektet.

async function getPost(postId: string) {
  const snapshot = await firestore().collection('posts').doc(postId).get();

  if (!snapshot.exists) {
    console.log('Post not found');
    return null;
  }

  const data = snapshot.data();
  return { id: snapshot.id, ...data };
}

Forespørgsel i en samling

Brug .where(field, operator, value) til at filtrere dokumenter, .orderBy(field, 'desc') til at sortere og .limit(n) til at begrænse resultaterne. Kæd flere kald til .where for OG-logik. Kald .get() for at udføre forespørgslen og modtage et QuerySnapshot.

Gennemgå resultaterne med snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })). Firestore kræver sammensatte indekser til forespørgsler, der filtrerer og sorterer efter forskellige felter — Firestore viser et link i loggen til oprettelse af det nødvendige indeks, hvis det mangler.

async function getUserPosts(userId: string) {
  const snapshot = await firestore()
    .collection('posts')
    .where('userId', '==', userId)
    .orderBy('createdAt', 'desc')
    .limit(20)
    .get();

  return snapshot.docs.map((doc) => ({
    id: doc.id,
    ...doc.data(),
  }));
}

Opdatering af et dokument

Brug .update() til at ændre bestemte felter uden at overskrive hele dokumentet. Kun de felter, du angiver, ændres — alle andre felter forbliver uændrede. Det adskiller sig fra .set(), som som standard erstatter hele dokumentet.

Brug firestore.FieldValue.increment(n) til atomisk at øge et numerisk felt uden først at læse det. Brug firestore.FieldValue.arrayUnion(item) og arrayRemove(item) til atomisk at tilføje eller fjerne elementer fra arrayfelter.

// Update specific fields
await firestore().collection('posts').doc(postId).update({
  title: 'Updated Title',
  updatedAt: firestore.FieldValue.serverTimestamp(),
});

// Atomic increment (e.g., a like counter)
await firestore().collection('posts').doc(postId).update({
  likesCount: firestore.FieldValue.increment(1),
});

// Add a tag to an array without duplicates
await firestore().collection('posts').doc(postId).update({
  tags: firestore.FieldValue.arrayUnion('react-native'),
});

Sletning af et dokument

Kald .delete() på en DocumentReference for at fjerne dokumentet. Dette sletter kun selve dokumentet, ikke eventuelle undersamlinger, det måtte indeholde. Hvis du vil slette undersamlinger, skal du rekursivt slette hvert dokument i dem — Firestore sletter ikke automatisk underliggende dokumenter.

Hvis du vil slette et enkelt felt fra et dokument uden at slette selve dokumentet, skal du bruge firestore.FieldValue.delete() i et .update()-kald med feltnavnet som nøgle.

// Delete a document
await firestore().collection('posts').doc(postId).delete();

// Delete a specific field within a document
await firestore().collection('users').doc(userId).update({
  temporaryData: firestore.FieldValue.delete(),
});

Batchskrivninger

En batchskrivning lader dig udføre flere oprettelses-, opdaterings- og slettehandlinger som én atomisk transaktion. Enten lykkes alle handlingerne, eller også lykkes ingen af dem. Det er afgørende for handlinger, der skal forblive konsistente, f.eks. overførsel af kreditter mellem brugere.

Opret en batch med firestore().batch(), tilføj handlinger med batch.set(), batch.update() og batch.delete(), og gennemfør den derefter med batch.commit(). Batches understøtter op til 500 handlinger ad gangen.

const batch = firestore().batch();

// Create a post
const postRef = firestore().collection('posts').doc();
batch.set(postRef, { title: 'Batch Post', userId });

// Increment user post count
const userRef = firestore().collection('users').doc(userId);
batch.update(userRef, { postCount: firestore.FieldValue.increment(1) });

// Execute both operations atomically
await batch.commit();
console.log('Batch write complete');

Firestores sikkerhedsregler

Firestores sikkerhedsregler styrer, hvem der kan læse og skrive dokumenter. Reglerne defineres i Firebase-konsollen under Firestore > Rules ved hjælp af et deklarativt DSL. Objektet request.auth giver dig adgang til den godkendte brugers UID i regeludtryk.

Start altid med afvis alt som standard, og tillad udtrykkeligt kun det, der er nødvendigt. En regel, der kun tillader en bruger at skrive til sit eget brugerdokument, ser sådan ud: allow write: if request.auth.uid == userId;

// firestore.rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Deny all by default
    match /{document=**} {
      allow read, write: if false;
    }

    // Users can read/write their own profile
    match /users/{userId} {
      allow read: if request.auth != null;
      allow write: if request.auth.uid == userId;
    }

    // Posts are public to read, but only the author can write
    match /posts/{postId} {
      allow read: if true;
      allow create: if request.auth != null;
      allow update, delete: if request.auth.uid == resource.data.userId;
    }
  }
}

Fletning af data med set og merge

Som standard overskriver .set(data) hele dokumentet. Hvis du vil flette nye data med eksisterende felter i stedet for at overskrive dem, skal du sende { merge: true } som det andet argument.

Det er nyttigt, når du vil oprette et dokument, hvis det ikke findes, eller opdatere det, hvis det gør — uden at kende alle dets aktuelle felter. Det er et mere fleksibelt alternativ til .update(), som kaster en fejl, hvis dokumentet ikke findes.

// set WITHOUT merge: overwrites the entire document
await firestore().collection('profiles').doc(userId).set({
  displayName: 'Alice',
});
// Existing fields like 'bio' would be DELETED

// set WITH merge: only updates specified fields
await firestore().collection('profiles').doc(userId).set({
  displayName: 'Alice',
}, { merge: true });
// Existing fields like 'bio' are preserved

Håndtering af offline-skrivninger

Firestore har en indbygget lokal cache og sætter skrivninger i kø, når enheden er offline. Når forbindelsen vender tilbage, sender Firestore automatisk de kølagte skrivninger til serveren i rækkefølge. Set fra appens perspektiv lykkes skrivningerne med det samme — brugergrænsefladen opdateres uden at vente på serveren.

Det betyder, at din React Native-app kan fungere fuldt ud uden internetforbindelse til både læsning og skrivning, mens Firestore håndterer synkroniseringen gennemsigtigt. Du kan registrere online/offline-statussen ved hjælp af en NetInfo-lytter, hvis du har brug for at vise forbindelsesstatus i brugergrænsefladen.

// Firestore enables offline persistence by default on mobile.
// This write succeeds even without internet connection:
await firestore().collection('drafts').doc(draftId).set({
  content: 'Work in progress...',
  savedAt: firestore.FieldValue.serverTimestamp(),
});
// When connectivity returns, Firestore syncs automatically.
// No additional code required.

Hurtig afprøvning

Afprøv din forståelse af begreberne inden for React Native Mobile Development fra denne lektion.

Opsummering af lektionen

I denne lektion lærte du: Firestores data-model med samlinger og dokumenter, hvordan du tilføjer, læser, opdaterer og sletter dokumenter ved hjælp af React Native Firebase SDK samt hvordan batchskrivninger sikrer atomiske handlinger på flere dokumenter. Dernæst tilføjer vi realtidslyttere for at modtage liveopdateringer fra Firestore og konfigurerer offline-lagring.

Gratis at komme i gang

Lær JavaScript med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “Læsning og skrivning af Firestore-dokumenter” gratis?

Ja — alle 3 lektioner i læringssporet React Native Academy, inklusive “Læsning og skrivning af Firestore-dokumenter”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. React Native Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Læsning og skrivning af Firestore-dokumenter”?

Tilføj, læs, opdatér og slet dokumenter i en Firestore-samling ved hjælp af Firestore-modulet, strukturér data med undersamlinger, og anvend sikkerhedsregler. Du øver dig i React Native Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på React Native Academy?

Der kræves ingen tidligere erfaring. React Native Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Læsning og skrivning af Firestore-dokumenter”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne React Native Academy-lektion?

Ja. Alle React Native Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Forbindelse af React Native Firebase til Deres projekt
  2. E-mail- og telefongodkendelse med Firebase
  3. Læsning og skrivning af Firestore-dokumenter
  4. Realtidslyttere og offline-persistens
← Tilbage til React Native Academy