1. Hinweis
In diesem Codelab erfahren Sie, wie Sie Firebase in eine Next.js-Webanwendung namens Friendly Eats einbinden, eine Website für Restaurantbewertungen.

Die fertige Webanwendung bietet nützliche Funktionen, die zeigen, wie Firebase Sie beim Erstellen von Next.js-Anwendungen unterstützen kann. Unter anderem sind folgende Funktionen verfügbar:
- Automatisches Erstellen und Bereitstellen: In diesem Codelab wird Firebase App Hosting verwendet, um Ihren Next.js-Code automatisch zu erstellen und bereitzustellen, wenn Sie ihn in einen konfigurierten Branch übertragen.
- An- und Abmeldung: In der fertigen Webanwendung können Sie sich über Google anmelden und abmelden. Nutzeranmeldung und -persistenz werden vollständig über Firebase Authentication verwaltet.
- Bilder: In der fertigen Webanwendung können angemeldete Nutzer Bilder von Restaurants hochladen. Bild-Assets werden in Cloud Storage for Firebase gespeichert. Das Firebase JavaScript SDK stellt eine öffentliche URL für hochgeladene Bilder bereit. Diese öffentliche URL wird dann im entsprechenden Restaurantdokument in Cloud Firestore gespeichert.
- Rezensionen: Mit der fertigen Web-App können angemeldete Nutzer Rezensionen zu Restaurants posten, die aus einer Sternebewertung und einer textbasierten Nachricht bestehen. Rezensionsinformationen werden in Cloud Firestore gespeichert.
- Filter: In der fertigen Web-App können angemeldete Nutzer die Liste der Restaurants nach Kategorie, Standort und Preis filtern. Sie können auch die verwendete Sortiermethode anpassen. Auf Daten wird über Cloud Firestore zugegriffen und Firestore-Abfragen werden basierend auf den verwendeten Filtern angewendet.
Vorbereitung
- Ein GitHub-Konto
- Kenntnisse in Next.js und JavaScript
Lerninhalte
- Firebase mit dem App Router von Next.js und serverseitigem Rendering verwenden
- Bilder in Cloud Storage for Firebase speichern
- Daten in einer Cloud Firestore-Datenbank lesen und schreiben
- Über Google anmelden mit dem Firebase JavaScript SDK verwenden
Voraussetzungen
- Git
- Eine aktuelle stabile Version von Node.js
- Einen Browser Ihrer Wahl, z. B. Google Chrome
- Eine Entwicklungsumgebung mit einem Code-Editor und einem Terminal
- Ein Google-Konto zum Erstellen und Verwalten Ihres Firebase-Projekts
- Die Möglichkeit, ein Upgrade Ihres Firebase-Projekts auf das Blaze-Preismodell durchzuführen
2. Entwicklungsumgebung und GitHub-Repository einrichten
In diesem Codelab wird die Starter-Codebasis der App bereitgestellt. Es wird die Firebase CLI verwendet.
GitHub-Repository erstellen
Die Codelab-Quelle finden Sie unter https://github.com/firebase/friendlyeats-web. Das Repository enthält Beispielprojekte für mehrere Plattformen. In diesem Codelab wird jedoch nur das Verzeichnis nextjs-start verwendet. Beachten Sie die folgenden Verzeichnisse:
* `nextjs-start`: contains the starter code upon which you build.
* `nextjs-end`: contains the solution code for the finished web app.
Kopieren Sie den Ordner nextjs-start in Ihr eigenes Repository:
- Erstellen Sie über ein Terminal einen neuen Ordner auf Ihrem Computer und wechseln Sie in das neue Verzeichnis:
mkdir codelab-friendlyeats-web cd codelab-friendlyeats-web - Verwenden Sie das npm-Paket giget, um nur den Ordner
nextjs-startabzurufen:npx giget@latest "gh:firebase/friendlyeats-web/nextjs-start#master" . --install - Änderungen lokal mit Git verfolgen:
git init git add . git commit -m "Codelab starting point" git branch -M main - Erstellen Sie ein neues GitHub-Repository: https://github.com/new. Geben Sie ihm einen beliebigen Namen.
- Kopieren Sie je nachdem, wie Sie sich bei GitHub authentifizieren (HTTPS oder SSH), die neue URL, die GitHub für Sie erstellt:
https://github.com/<USER_NAME>/<REPOSITORY_NAME>.gitodergit@github.com:<USER_NAME>/<REPOSITORY_NAME>.git
- Übertragen Sie die lokalen Änderungen per Push in Ihr neues GitHub-Repository, indem Sie den folgenden Befehl ausführen. Ersetzen Sie den Platzhalter
<REPOSITORY_URL>durch die tatsächliche Repository-URL.git remote add origin <REPOSITORY_URL> git push -u origin main - Der Starter-Code sollte jetzt in Ihrem GitHub-Repository angezeigt werden.
Firebase CLI installieren oder aktualisieren
Führen Sie den folgenden Befehl aus, um zu prüfen, ob die Firebase CLI installiert ist und ob es sich um Version 14.1.0 oder höher handelt:
firebase --version
Wenn Sie eine niedrigere Version sehen oder die Firebase CLI nicht installiert ist, führen Sie den Installationsbefehl aus:
npm install -g firebase-tools@latest
Wenn Sie die Firebase CLI aufgrund von Berechtigungsfehlern nicht installieren können, lesen Sie die npm-Dokumentation oder verwenden Sie eine andere Installationsoption.
In Firebase anmelden
- Führen Sie den folgenden Befehl aus, um sich in der Firebase CLI anzumelden:
firebase login
- Geben Sie je nachdem, ob Firebase Daten erheben soll,
YoderNein. - Wählen Sie in Ihrem Browser Ihr Google-Konto aus und klicken Sie auf Zulassen.
3. Das Firebase-Projekt einrichten
In diesem Abschnitt richten Sie ein Firebase-Projekt ein und verknüpfen eine Firebase-Web-App damit. Außerdem richten Sie die Firebase-Dienste ein, die von der Beispiel-Web-App verwendet werden.
Firebase-Projekt erstellen
- Melden Sie sich mit demselben Google-Konto, das Sie im vorherigen Schritt verwendet haben, in der Firebase Console an.
- Klicken Sie auf die Schaltfläche, um ein neues Projekt zu erstellen, und geben Sie einen Projektnamen ein (z. B.
FriendlyEats Codelab).
- Klicken Sie auf Weiter.
- Wenn Sie dazu aufgefordert werden, lesen und akzeptieren Sie die Nutzungsbedingungen von Firebase und klicken Sie dann auf Weiter.
- (Optional) Aktivieren Sie die KI-Unterstützung in der Firebase Console (als „Gemini in Firebase“ bezeichnet).
- Für dieses Codelab benötigen Sie Google Analytics nicht. Deaktivieren Sie daher die Google Analytics-Option.
- Klicken Sie auf Projekt erstellen, warten Sie, bis Ihr Projekt bereitgestellt wurde, und klicken Sie dann auf Weiter.
Firebase-Tarif upgraden
Wenn Sie Firebase App Hosting und Cloud Storage for Firebase verwenden möchten, muss Ihr Firebase-Projekt das Blaze-Preismodell (Pay as you go) nutzen. Das bedeutet, dass es mit einem Cloud-Rechnungskonto verknüpft ist.
- Für ein Cloud-Rechnungskonto ist eine Zahlungsmethode wie eine Kreditkarte erforderlich.
- Wenn Sie neu bei Firebase und Google Cloud sind, prüfen Sie, ob Sie Anspruch auf ein Guthaben von 300 $ und ein Cloud-Rechnungskonto für den kostenlosen Testzeitraum haben.
- Wenn Sie dieses Codelab im Rahmen einer Veranstaltung absolvieren, fragen Sie den Organisator, ob Cloud-Guthaben verfügbar ist.
So führen Sie ein Upgrade Ihres Projekts auf den Blaze-Tarif durch:
- Wählen Sie in der Firebase Console die Option Upgrade aus.
- Wählen Sie den Blaze-Tarif aus. Folgen Sie der Anleitung auf dem Bildschirm, um ein Cloud-Rechnungskonto mit Ihrem Projekt zu verknüpfen.
Wenn Sie im Rahmen dieses Upgrades ein Cloud-Rechnungskonto erstellen mussten, müssen Sie möglicherweise in der Firebase Console zum Upgrade-Vorgang zurückkehren, um das Upgrade abzuschließen.
Ihrem Firebase-Projekt eine Web-App hinzufügen
- Rufen Sie in Ihrem Firebase-Projekt die Projektübersicht auf, klicken Sie auf App hinzufügen und dann auf Web.
- Geben Sie im Textfeld App-Alias einen einprägsamen App-Alias ein, z. B.
My Next.js app. - Lassen Sie das Kästchen Firebase Hosting für diese App einrichten deaktiviert.
- Klicken Sie auf App registrieren > Weiter zur Konsole.
Firebase-Dienste in der Firebase Console einrichten
Authentifizierung einrichten
- Maximieren Sie im linken Bereich der Firebase Console Build und wählen Sie dann Authentication aus.
- Klicken Sie auf Jetzt starten.
- Klicken Sie in der Spalte Anbieter für Anmeldungen auf Google > Aktivieren.
- Geben Sie im Textfeld Öffentlicher Name für Projekt einen einprägsamen Namen ein, z. B.
My Next.js app. - Wählen Sie im Drop-down-Menü Support-E-Mail-Adresse für Projekt Ihre E-Mail-Adresse aus.
- Klicken Sie auf Speichern.
Cloud Firestore einrichten
- Maximieren Sie im linken Bereich der Firebase Console Erstellen und wählen Sie dann Firestore-Datenbank aus.
- Klicken Sie auf Datenbank erstellen.
- Wählen Sie Standard Edition aus und klicken Sie auf Weiter.
- Ändern Sie die Datenbank-ID nicht, sondern belassen Sie sie auf
(default). - Wählen Sie einen Standort für Ihre Datenbank aus und klicken Sie auf Weiter.
Für eine echte Anwendung sollten Sie einen Standort in der Nähe Ihrer Nutzer auswählen. - Klicken Sie auf Im Testmodus starten. Lesen Sie den Haftungsausschluss zu den Sicherheitsregeln.
Später in diesem Codelab fügen Sie Sicherheitsregeln hinzu, um Ihre Daten zu schützen. Veröffentlichen Sie eine App nicht, ohne Sicherheitsregeln für Ihre Datenbank hinzuzufügen. - Klicken Sie auf Erstellen.
Cloud Storage for Firebase einrichten
- Maximieren Sie im linken Bereich der Firebase Console Build und wählen Sie dann Storage aus.
- Klicken Sie auf Jetzt starten.
- Wählen Sie einen Standort für Ihren Standard-Storage-Bucket aus.
Buckets inUS-WEST1,US-CENTRAL1undUS-EAST1können die Always Free-Stufe für Google Cloud Storage nutzen. Für Buckets an allen anderen Standorten gelten die Preise und die Nutzung von Google Cloud Storage. - Klicken Sie auf Im Testmodus starten. Lesen Sie den Haftungsausschluss zu den Sicherheitsregeln.
Später in diesem Codelab fügen Sie Sicherheitsregeln hinzu, um Ihre Daten zu schützen. Verteilen oder veröffentlichen Sie eine App nicht, ohne Sicherheitsregeln für Ihren Storage-Bucket hinzuzufügen. - Klicken Sie auf Erstellen.
Sicherheitsregeln bereitstellen
Der Code enthält bereits Sicherheitsregeln für Firestore und Cloud Storage for Firebase. Nachdem Sie die Sicherheitsregeln bereitgestellt haben, sind die Daten in Ihrer Datenbank und Ihrem Bucket besser vor Missbrauch geschützt.
- Konfigurieren Sie in Ihrem Terminal die Befehlszeile so, dass das zuvor erstellte Firebase-Projekt verwendet wird:
Wenn Sie nach einem Alias gefragt werden, geben Siefirebase use --add
friendlyeats-codelabein. - Führen Sie den folgenden Befehl im Terminal aus, um diese Sicherheitsregeln (und die später benötigten Indexe) bereitzustellen:
firebase deploy --only firestore,storage
- Wenn Sie gefragt werden:
"Cloud Storage for Firebase needs an IAM Role to use cross-service rules. Grant the new role?", drücken SieEnter, um Ja auszuwählen.
4. Starter-Codebasis prüfen
In diesem Abschnitt sehen Sie sich einige Bereiche der Starter-Codebasis der App an, denen Sie in diesem Codelab Funktionen hinzufügen werden.
Ordner- und Dateistruktur
Die folgende Tabelle enthält eine Übersicht über die Ordner- und Dateistruktur der App:
Ordner und Dateien | Beschreibung |
| React-Komponenten für Filter, Überschriften, Restaurantdetails und Rezensionen |
| Dienstfunktionen, die nicht unbedingt an React oder Next.js gebunden sind |
| Firebase-spezifischer Code und Firebase-Konfiguration |
| Statische Assets in der Web-App, z. B. Symbole |
| Routing mit dem Next.js-App-Router |
| Projektabhängigkeiten mit npm |
| Next.js-spezifische Konfiguration (Serveraktionen sind aktiviert) |
| Konfiguration des JavaScript-Sprachdienstes |
Server- und Clientkomponenten
Die Anwendung ist eine Next.js-Webanwendung, die den App-Router verwendet. In der gesamten Anwendung wird Server-Rendering verwendet. Die Datei src/app/page.js ist beispielsweise eine Serverkomponente, die für die Hauptseite verantwortlich ist. Die Datei src/components/RestaurantListings.jsx ist eine Clientkomponente, die durch die Anweisung "use client" am Anfang der Datei gekennzeichnet ist.
Importanweisungen
Möglicherweise sehen Sie Importanweisungen wie die folgenden:
import RatingPicker from "@/src/components/RatingPicker.jsx";
Die App verwendet das Symbol @, um unhandliche relative Importpfade zu vermeiden. Dies wird durch Pfad-Aliasse ermöglicht.
Firebase-spezifische APIs
Der gesamte Firebase API-Code befindet sich im Verzeichnis src/lib/firebase. Einzelne React-Komponenten importieren dann die verpackten Funktionen aus dem Verzeichnis src/lib/firebase, anstatt Firebase-Funktionen direkt zu importieren.
Mock-Daten
Die Datei src/lib/randomData.js enthält fiktive Restaurant- und Rezensionsdaten. Die Daten aus dieser Datei werden im Code in der Datei src/lib/fakeRestaurants.js zusammengestellt.
5. App-Hosting-Backend erstellen
In diesem Abschnitt richten Sie ein App Hosting-Backend ein, um einen Zweig in Ihrem Git-Repository zu beobachten.
Am Ende dieses Abschnitts haben Sie ein App Hosting-Backend, das mit Ihrem Repository in GitHub verbunden ist. Dieses Backend erstellt automatisch eine neue Version Ihrer App und stellt sie bereit, wenn Sie einen neuen Commit an Ihren main-Zweig übertragen.
Backend erstellen
- Rufen Sie in der Firebase Console die Seite App Hosting auf.
- Klicken Sie auf Jetzt starten, um mit der Erstellung des Back-Ends zu beginnen.
- Wählen Sie eine Region aus. Für eine echte App würden Sie die Region auswählen, die Ihren Nutzern am nächsten ist.
- Folgen Sie den Aufforderungen im Schritt GitHub-Repository importieren, um die GitHub-Authentifizierung einzurichten.
- Wählen Sie unter Repository die Option Zugriff auf ein neues Repository in GitHub gewähren aus und folgen Sie den Aufforderungen, um den Zugriff auf das zuvor erstellte GitHub-Repository zu aktivieren.
- Klicken Sie auf Liste aktualisieren, um die Liste zu aktualisieren. Wählen Sie dann Ihr Repository aus und klicken Sie auf Weiter.
- Legen Sie die Bereitstellungseinstellungen fest:
- Legen Sie den Live-Zweig auf
mainfest. - Behalten Sie das Stammverzeichnis als
/bei. - Automatische Roll-outs aktivieren
- Legen Sie den Live-Zweig auf
- Geben Sie dem Backend den Namen
friendlyeats-codelabund klicken Sie auf Weiter. - Wählen Sie unter Firebase Web-App verknüpfen die Option Vorhandene Firebase Web-App auswählen und dann die hinzugefügte App aus der Liste aus.
- Klicken Sie auf Fertigstellen und bereitstellen. Sie werden zu einer neuen Seite weitergeleitet, auf der Sie den Status Ihres neuen App Hosting-Backends sehen können.
- Klicken Sie auf Anzeigen, um weitere Informationen zu Ihrer App Hosting-Bereitstellung aufzurufen, einschließlich Roll-out-Status, Logs und Nutzungsdetails.
- Klicken Sie nach Abschluss des Roll-outs unter Domains auf die URL Ihrer Website, um sie zu öffnen. Aufgrund der DNS-Weitergabe kann es einige Minuten dauern, bis die Funktion verfügbar ist.
- Hoppla! Beim Laden der Seite wird die Fehlermeldung „Anwendungsfehler: Es ist eine serverseitige Ausnahme aufgetreten (weitere Informationen finden Sie in den Server-Logs)“ angezeigt.
- Sehen Sie sich in der Firebase Console den Tab Logs Ihres App Hosting-Backends an. Sie sehen den Logeintrag „Error: not implemented“. Das beheben wir im nächsten Schritt, wenn wir die Authentifizierung hinzufügen.
Sie haben die erste Webanwendung bereitgestellt. Jedes Mal, wenn Sie einen neuen Commit per Push in den Branch main Ihres GitHub-Repositorys übertragen, wird in der Firebase Console ein neuer Build und Roll-out gestartet. Ihre Website wird nach Abschluss des Roll-outs automatisch aktualisiert.
6. Authentifizierung zur Web-App hinzufügen
In diesem Abschnitt fügen Sie der Webanwendung eine Authentifizierung hinzu, damit Sie sich darin anmelden können.
Fügen Sie eine autorisierte Domain hinzu
Firebase Authentication akzeptiert nur Anmeldeanfragen von Domains, die Sie zulassen. Hier fügen wir die Domain Ihres App Hosting-Backends der Liste der genehmigten Domains in Ihrem Projekt hinzu.
- Öffnen Sie die Seite App Hosting und klicken Sie unter Ihrer bereitgestellten Website auf Ansehen, um die Seite Übersicht aufzurufen. Kopieren Sie den Domainnamen Ihres App Hosting-Backends.
- Rufen Sie den Tab Auth Settings (Authentifizierungseinstellungen) auf und wählen Sie das Projekt aus, dem Sie eine autorisierte Domain hinzufügen möchten. Suchen Sie dann den Bereich Autorisierte Domains und klicken Sie darauf.
- Klicken Sie auf Domain hinzufügen.
- Geben Sie die Domain Ihres App Hosting-Backends ein.
- Klicken Sie auf Hinzufügen.
Anmelde- und Abmeldefunktionen implementieren
Ersetzen Sie in der Datei src/lib/firebase/auth.js die Funktionen onAuthStateChanged, onIdTokenChanged, signInWithGoogle und signOut durch den folgenden Code:
export function onAuthStateChanged(cb) {
return _onAuthStateChanged(auth, cb);
}
export function onIdTokenChanged(cb) {
return _onIdTokenChanged(auth, cb);
}
export async function signInWithGoogle() {
const provider = new GoogleAuthProvider();
try {
await signInWithPopup(auth, provider);
} catch (error) {
console.error("Error signing in with Google", error);
}
}
export async function signOut() {
try {
return auth.signOut();
} catch (error) {
console.error("Error signing out with Google", error);
}
}
In diesem Code werden die folgenden Firebase APIs verwendet:
Firebase API | Beschreibung |
Fügt einen Beobachter für Änderungen am Anmeldestatus des Nutzers hinzu. | |
Fügt einen Beobachter für Änderungen am ID-Token des Nutzers hinzu. | |
Erstellt eine Google-Authentifizierungsanbieterinstanz. | |
Startet einen dialogbasierten Authentifizierungsablauf. | |
Meldet den Nutzer ab. |
In der Datei src/components/Header.jsx ruft der Code bereits die Funktionen signInWithGoogle und signOut auf.
Authentifizierungsstatus an den Server senden
Wir verwenden Cookies, um den Authentifizierungsstatus an den Server zu übergeben. Immer wenn sich der Authentifizierungsstatus im Client ändert, wird das __session-Cookie aktualisiert.
Ersetzen Sie in src/components/Header.jsx die Funktion useUserSession durch den folgenden Code:
function useUserSession(initialUser) {
useEffect(() => {
return onIdTokenChanged(async (user) => {
if (user) {
const idToken = await user.getIdToken();
await setCookie("__session", idToken);
} else {
await deleteCookie("__session");
}
if (initialUser?.uid === user?.uid) {
return;
}
window.location.reload();
});
}, [initialUser]);
return initialUser;
}
Authentifizierungsstatus auf dem Server lesen
Wir verwenden FirebaseServerApp, um den Authentifizierungsstatus des Clients auf dem Server zu spiegeln.
Öffnen Sie src/lib/firebase/serverApp.js und ersetzen Sie die Funktion getAuthenticatedAppForUser:
export async function getAuthenticatedAppForUser() {
const authIdToken = (await cookies()).get("__session")?.value;
// Firebase Server App is a new feature in the JS SDK that allows you to
// instantiate the SDK with credentials retrieved from the client & has
// other affordances for use in server environments.
const firebaseServerApp = initializeServerApp(
// https://github.com/firebase/firebase-js-sdk/issues/8863#issuecomment-2751401913
initializeApp(),
{
authIdToken,
}
);
const auth = getAuth(firebaseServerApp);
await auth.authStateReady();
return { firebaseServerApp, currentUser: auth.currentUser };
}
Änderungen prüfen
Das Root-Layout in der Datei src/app/layout.js rendert den Header und übergibt den Nutzer, falls verfügbar, als Prop.
<Header initialUser={currentUser?.toJSON()} />
Das bedeutet, dass die Komponente <Header> während der Serverlaufzeit Nutzerdaten rendert, sofern verfügbar. Wenn es während des Seitenlebenszyklus nach dem ersten Seitenaufbau Authentifizierungsaktualisierungen gibt, werden diese vom onAuthStateChanged-Handler verarbeitet.
Jetzt ist es an der Zeit, einen neuen Build bereitzustellen und zu prüfen, was Sie erstellt haben.
- Erstellen Sie einen Commit mit der Commit-Nachricht „Add authentication“ und übertragen Sie ihn per Push in Ihr GitHub-Repository.
git add . git commit -m "Add authentication" git push - Öffnen Sie die Seite „App Hosting“ und klicken Sie nach Abschluss des neuen Roll-outs auf die Website-URL, um sie zu öffnen.
- Authentifizierung testen:
- Melden Sie sich mit Ihrem Google-Konto an und prüfen Sie, ob Ihr Anzeigename nach der Anmeldung in der Kopfzeile angezeigt wird.
- Melden Sie sich ab und wieder an. Sie können diesen Schritt mit verschiedenen Nutzern wiederholen.
- Optional: Rechtsklicken Sie auf die Web-App, wählen Sie Seitenquelltext anzeigen aus und suchen Sie nach dem Anzeigenamen. Sie wird in der vom Server zurückgegebenen HTML-Rohquelle angezeigt.
7. Informationen zu Restaurants ansehen
Die Web-App enthält Mock-Daten für Restaurants und Rezensionen.
Ein oder mehrere Restaurants hinzufügen
So fügen Sie simulierte Restaurantdaten in Ihre lokale Cloud Firestore-Datenbank ein:
- Melde dich in der Web-App an, falls du das noch nicht getan hast. Wählen Sie dann
> Beispielrestaurants hinzufügen aus. In der Friendly Eats-Webanwendung werden keine Restaurants angezeigt, da wir noch keinen Code zum Abrufen von Daten eingerichtet haben. Das beheben wir im nächsten Schritt. - Wählen Sie in der Firebase Console auf der Seite Firestore Database die Option restaurants aus. Sie sehen die Dokumente der obersten Ebene in der Sammlung „restaurants“, die jeweils ein Restaurant darstellen.
- Klicken Sie auf einige Dokumente, um die Attribute eines Restaurantdokuments zu untersuchen.
Liste der Restaurants anzeigen
Ihre Cloud Firestore-Datenbank enthält jetzt Restaurants, die in der Next.js-Webanwendung angezeigt werden können.
So definieren Sie den Code zum Abrufen von Daten:
- Suchen Sie in der Datei
src/app/page.jsdie Serverkomponente<Home />und sehen Sie sich den Aufruf der FunktiongetRestaurantsan, die zur Laufzeit des Servers eine Liste von Restaurants abruft. In den folgenden Schritten implementieren Sie die FunktiongetRestaurants. - Ersetzen Sie in der Datei
src/lib/firebase/firestore.jsdie FunktionenapplyQueryFiltersundgetRestaurantsdurch den folgenden Code:
function applyQueryFilters(q, { category, city, price, sort }) {
if (category) {
q = query(q, where("category", "==", category));
}
if (city) {
q = query(q, where("city", "==", city));
}
if (price) {
q = query(q, where("price", "==", price.length));
}
if (sort === "Rating" || !sort) {
q = query(q, orderBy("avgRating", "desc"));
} else if (sort === "Review") {
q = query(q, orderBy("numRatings", "desc"));
}
return q;
}
export async function getRestaurants(db = db, filters = {}) {
let q = query(collection(db, "restaurants"));
q = applyQueryFilters(q, filters);
const results = await getDocs(q);
return results.docs.map((doc) => {
return {
id: doc.id,
...doc.data(),
// Only plain objects can be passed to Client Components from Server Components
timestamp: doc.data().timestamp.toDate(),
};
});
}
- Erstellen Sie einen Commit mit der Commit-Nachricht „Read the list of restaurants from Firestore“ und übertragen Sie ihn per Push in Ihr GitHub-Repository.
git add . git commit -m "Read the list of restaurants from Firestore" git push - Öffnen Sie die Seite „App Hosting“ in der Firebase Console und warten Sie, bis der neue Roll-out abgeschlossen ist.
- Aktualisieren Sie die Seite in der Web-App. Bilder des Restaurants werden als Kacheln auf der Seite angezeigt.
Prüfen, ob die Restaurantlisten zur Serverlaufzeit geladen werden
Wenn Sie das Next.js-Framework verwenden, ist es möglicherweise nicht offensichtlich, wann Daten zur Serverlaufzeit oder zur clientseitigen Laufzeit geladen werden.
So prüfen Sie, ob die Restaurantlisten zur Serverlaufzeit geladen werden:
- Öffnen Sie in der Web-App die Entwicklertools und deaktivieren Sie JavaScript.

- Aktualisieren Sie die Web-App. Die Restaurantlisten werden weiterhin geladen. Die Restaurantinformationen werden in der Serverantwort zurückgegeben. Wenn JavaScript aktiviert ist, werden die Restaurantinformationen über den clientseitigen JavaScript-Code hydriert.
- Aktiviere JavaScript wieder in den Entwicklertools.
Mit Cloud Firestore-Snapshot-Listenern auf Restaurant-Updates warten
Im vorherigen Abschnitt haben Sie gesehen, wie die ersten Restaurants aus der Datei src/app/page.js geladen wurden. Die Datei src/app/page.js ist eine Serverkomponente und wird auf dem Server gerendert, einschließlich des Firebase-Codes zum Abrufen von Daten.
Die Datei src/components/RestaurantListings.jsx ist eine Clientkomponente und kann so konfiguriert werden, dass sie serverseitig gerendertes Markup hydriert.
So konfigurieren Sie die Datei src/components/RestaurantListings.jsx, um serverseitig gerendertes Markup zu hydratisieren:
- Sehen Sie sich in der Datei
src/components/RestaurantListings.jsxden folgenden Code an, der bereits für Sie geschrieben wurde:
useEffect(() => {
return getRestaurantsSnapshot((data) => {
setRestaurants(data);
}, filters);
}, [filters]);
Dieser Code ruft die Funktion getRestaurantsSnapshot() auf, die der Funktion getRestaurants() ähnelt, die Sie in einem vorherigen Schritt implementiert haben. Diese Snapshot-Funktion bietet jedoch einen Callback-Mechanismus, sodass der Callback jedes Mal aufgerufen wird, wenn eine Änderung an der Sammlung des Restaurants vorgenommen wird.
- Ersetzen Sie in der Datei
src/lib/firebase/firestore.jsdie FunktiongetRestaurantsSnapshot()durch den folgenden Code:
export function getRestaurantsSnapshot(cb, filters = {}) {
if (typeof cb !== "function") {
console.log("Error: The callback parameter is not a function");
return;
}
let q = query(collection(db, "restaurants"));
q = applyQueryFilters(q, filters);
return onSnapshot(q, (querySnapshot) => {
const results = querySnapshot.docs.map((doc) => {
return {
id: doc.id,
...doc.data(),
// Only plain objects can be passed to Client Components from Server Components
timestamp: doc.data().timestamp.toDate(),
};
});
cb(results);
});
}
- Ersetzen Sie in der Datei
src/lib/firebase/firestore.jsdie FunktiongetRestaurantSnapshotById()durch den folgenden Code:
export function getRestaurantSnapshotById(restaurantId, cb) {
if (!restaurantId) {
console.log("Error: Invalid ID received: ", restaurantId);
return;
}
if (typeof cb !== "function") {
console.log("Error: The callback parameter is not a function");
return;
}
const docRef = doc(db, "restaurants", restaurantId);
return onSnapshot(docRef, (docSnap) => {
cb({
...docSnap.data(),
timestamp: docSnap.data().timestamp.toDate(),
});
});
}
Änderungen, die Sie auf der Seite Firestore-Datenbank vornehmen, werden jetzt in Echtzeit in der Webanwendung angezeigt.
- Erstellen Sie einen Commit mit der Commit-Nachricht „Listen for realtime restaurant updates“ und übertragen Sie ihn per Push in Ihr GitHub-Repository.
git add . git commit -m "Listen for realtime restaurant updates" git push - Öffnen Sie die Seite „App Hosting“ in der Firebase Console und warten Sie, bis der neue Roll-out abgeschlossen ist.
- Wählen Sie in der Webanwendung
> Beispielrestaurants hinzufügen aus. Wenn die Snapshot-Funktion richtig implementiert ist, werden die Restaurants in Echtzeit angezeigt, ohne dass die Seite aktualisiert werden muss.
8. Von Nutzern eingereichte Rezensionen aus der Web-App speichern
- Ersetzen Sie in der Datei
src/lib/firebase/firestore.jsdie FunktionupdateWithRating()durch den folgenden Code:
const updateWithRating = async (
transaction,
docRef,
newRatingDocument,
review
) => {
const restaurant = await transaction.get(docRef);
const data = restaurant.data();
const newNumRatings = data?.numRatings ? data.numRatings + 1 : 1;
const newSumRating = (data?.sumRating || 0) + Number(review.rating);
const newAverage = newSumRating / newNumRatings;
transaction.update(docRef, {
numRatings: newNumRatings,
sumRating: newSumRating,
avgRating: newAverage,
});
transaction.set(newRatingDocument, {
...review,
timestamp: Timestamp.fromDate(new Date()),
});
};
Mit diesem Code wird ein neues Firestore-Dokument eingefügt, das die neue Rezension darstellt. Außerdem wird das vorhandene Firestore-Dokument, das das Restaurant darstellt, mit aktualisierten Zahlen für die Anzahl der Bewertungen und die durchschnittliche berechnete Bewertung aktualisiert.
- Ersetzen Sie die Funktion
addReviewToRestaurant()durch den folgenden Code:
export async function addReviewToRestaurant(db, restaurantId, review) {
if (!restaurantId) {
throw new Error("No restaurant ID has been provided.");
}
if (!review) {
throw new Error("A valid review has not been provided.");
}
try {
const docRef = doc(collection(db, "restaurants"), restaurantId);
const newRatingDocument = doc(
collection(db, `restaurants/${restaurantId}/ratings`),
);
// corrected line
await runTransaction(db, (transaction) =>
updateWithRating(transaction, docRef, newRatingDocument, review),
);
} catch (error) {
console.error(
"There was an error adding the rating to the restaurant",
error,
);
throw error;
}
}
Next.js-Serveraktion implementieren
Eine Next.js-Serveraktion bietet eine praktische API für den Zugriff auf Formulardaten, z. B. data.get("text"), um den Textwert aus der Nutzlast des gesendeten Formulars abzurufen.
So verwenden Sie eine Next.js-Serveraktion, um das Senden des Rezensionsformulars zu verarbeiten:
- Suchen Sie in der Datei
src/components/ReviewDialog.jsxim Element<form>nach dem Attributaction.
<form
action={handleReviewFormSubmission}
onSubmit={() => {
handleClose();
}}
>
Der Attributwert action bezieht sich auf eine Funktion, die Sie im nächsten Schritt implementieren.
- Ersetzen Sie in der Datei
src/app/actions.jsdie FunktionhandleReviewFormSubmission()durch den folgenden Code:
export async function handleReviewFormSubmission(data) {
const { firebaseServerApp } = await getAuthenticatedAppForUser();
const db = getFirestore(firebaseServerApp);
await addReviewToRestaurant(db, data.get("restaurantId"), {
text: data.get("text"),
rating: data.get("rating"),
// This came from a hidden form field.
userId: data.get("userId"),
});
}
Rezensionen für ein Restaurant hinzufügen
Sie haben die Unterstützung für das Einreichen von Rezensionen implementiert und können jetzt prüfen, ob Ihre Rezensionen korrekt in Cloud Firestore eingefügt werden.
So fügen Sie eine Rezension hinzu und prüfen, ob sie in Cloud Firestore eingefügt wurde:
- Erstellen Sie einen Commit mit der Commit-Nachricht „Allow users to submit restaurant reviews“ und übertragen Sie ihn per Push in Ihr GitHub-Repository.
git add . git commit -m "Allow users to submit restaurant reviews" git push - Öffnen Sie die Seite „App Hosting“ in der Firebase Console und warten Sie, bis der neue Roll-out abgeschlossen ist.
- Aktualisieren Sie die Web-App und wählen Sie auf der Startseite ein Restaurant aus.
- Klicken Sie auf der Seite des Restaurants auf
. - Wählen Sie eine Bewertung aus.
- Schreiben Sie eine Rezension.
- Klicken Sie auf Senden. Ihre Rezension wird oben in der Liste der Rezensionen angezeigt.
- Suchen Sie in Cloud Firestore im Bereich Dokument hinzufügen nach dem Dokument des Restaurants, das Sie bewertet haben, und wählen Sie es aus.
- Wählen Sie im Bereich Sammlung starten die Option Bewertungen aus.
- Suchen Sie im Bereich Dokument hinzufügen nach dem Dokument, das Sie prüfen möchten, um sicherzustellen, dass es wie erwartet eingefügt wurde.
9. Von Nutzern hochgeladene Dateien aus der Web-App speichern
In diesem Abschnitt fügen Sie eine Funktion hinzu, mit der Sie das mit einem Restaurant verknüpfte Bild ersetzen können, wenn Sie angemeldet sind. Sie laden das Bild in Firebase Storage hoch und aktualisieren die Bild-URL im Cloud Firestore-Dokument, das das Restaurant darstellt.
So speichern Sie von Nutzern hochgeladene Dateien aus der Web-App:
- Sehen Sie sich in der Datei
src/components/Restaurant.jsxden Code an, der ausgeführt wird, wenn der Nutzer eine Datei hochlädt:
async function handleRestaurantImage(target) {
const image = target.files ? target.files[0] : null;
if (!image) {
return;
}
const imageURL = await updateRestaurantImage(id, image);
setRestaurantDetails({ ...restaurantDetails, photo: imageURL });
}
An dieser Funktion müssen keine Änderungen vorgenommen werden. Das Verhalten der Funktion updateRestaurantImage() wird in den folgenden Schritten implementiert.
- Ersetzen Sie in der Datei
src/lib/firebase/storage.jsdie FunktionenupdateRestaurantImage()unduploadImage()durch den folgenden Code:
export async function updateRestaurantImage(restaurantId, image) {
try {
if (!restaurantId) {
throw new Error("No restaurant ID has been provided.");
}
if (!image || !image.name) {
throw new Error("A valid image has not been provided.");
}
const publicImageUrl = await uploadImage(restaurantId, image);
await updateRestaurantImageReference(restaurantId, publicImageUrl);
return publicImageUrl;
} catch (error) {
console.error("Error processing request:", error);
}
}
async function uploadImage(restaurantId, image) {
const filePath = `images/${restaurantId}/${image.name}`;
const newImageRef = ref(storage, filePath);
await uploadBytesResumable(newImageRef, image);
return await getDownloadURL(newImageRef);
}
Die Funktion updateRestaurantImageReference() ist bereits für Sie implementiert. Diese Funktion aktualisiert ein vorhandenes Restaurantdokument in Cloud Firestore mit einer aktualisierten Bild-URL.
Funktion zum Hochladen von Bildern prüfen
So prüfen Sie, ob das Image wie erwartet hochgeladen wird:
- Erstellen Sie einen Commit mit der Commit-Nachricht „Allow users to change each restaurants' photo“ und übertragen Sie ihn per Push in Ihr GitHub-Repository.
git add . git commit -m "Allow users to change each restaurants' photo" git push - Öffnen Sie die Seite „App Hosting“ in der Firebase Console und warten Sie, bis der neue Roll-out abgeschlossen ist.
- Prüfen Sie in der Web-App, ob Sie angemeldet sind, und wählen Sie ein Restaurant aus.
- Klicken Sie auf
und laden Sie ein Bild aus Ihrem Dateisystem hoch. Ihr Bild wird aus Ihrer lokalen Umgebung in Cloud Storage hochgeladen. Das Bild wird sofort nach dem Hochladen angezeigt. - Rufen Sie Cloud Storage for Firebase auf.
- Rufen Sie den Ordner auf, der das Restaurant darstellt. Das hochgeladene Bild ist im Ordner vorhanden.

10. Restaurantrezensionen mit generativer KI zusammenfassen
In diesem Abschnitt fügen Sie eine Funktion für Rezensionsüberblicke hinzu, damit Nutzer schnell sehen können, was andere über ein Restaurant denken, ohne jede Rezension lesen zu müssen.
Gemini API-Schlüssel in Cloud Secret Manager speichern
- Zur Verwendung der Gemini API benötigen Sie einen API-Schlüssel. Rufen Sie Google AI Studio auf und klicken Sie auf API-Schlüssel erstellen.
- Geben Sie dem Schlüssel einen beliebigen Namen. Wenn Ihr Projekt nicht unter Importiertes Projekt auswählen aufgeführt ist, klicken Sie auf Projekt importieren, setzen Sie ein Häkchen neben Ihrem Projekt in der Liste und klicken Sie dann auf Importieren. Wählen Sie es dann unter Importiertes Projekt auswählen aus und klicken Sie auf Schlüssel erstellen.
- App Hosting ist in Cloud Secret Manager eingebunden, damit Sie vertrauliche Werte wie API-Schlüssel sicher speichern können:
- Führen Sie in einem Terminal den Befehl zum Erstellen eines neuen Secrets aus:
firebase apphosting:secrets:set GEMINI_API_KEY- Wenn Sie nach dem Secret-Wert gefragt werden, kopieren Sie Ihren Gemini API-Schlüssel aus Google AI Studio und fügen Sie ihn ein.
- Wenn Sie gefragt werden, ob das neue Secret für die Produktion oder für lokale Tests bestimmt ist, wählen Sie „Produktion“ aus.
- Wenn Sie gefragt werden, ob Sie Zugriff gewähren möchten, damit das Dienstkonto Ihres Back-Ends auf das Secret zugreifen kann, wählen Sie „Ja“ aus.
- Wenn Sie gefragt werden, ob das neue Secret zu
apphosting.yamlhinzugefügt werden soll, geben SieYein, um zuzustimmen.
Ihr Gemini API-Schlüssel wird jetzt sicher in Cloud Secret Manager gespeichert und ist für Ihr App Hosting-Backend zugänglich.
Komponente für den Rezensionsüberblick implementieren
- Ersetzen Sie in
src/components/Reviews/ReviewSummary.jsxdie FunktionGeminiSummarydurch den folgenden Code:export async function GeminiSummary({ restaurantId }) { const { firebaseServerApp } = await getAuthenticatedAppForUser(); const reviews = await getReviewsByRestaurantId( getFirestore(firebaseServerApp), restaurantId ); const reviewSeparator = "@"; const prompt = ` Based on the following restaurant reviews, where each review is separated by a '${reviewSeparator}' character, create a one-sentence summary of what people think of the restaurant. Here are the reviews: ${reviews.map((review) => review.text).join(reviewSeparator)} `; try { if (!process.env.GEMINI_API_KEY) { // Make sure GEMINI_API_KEY environment variable is set: // https://genkit.dev/docs/get-started/ throw new Error( 'GEMINI_API_KEY not set. Set it with "firebase apphosting:secrets:set GEMINI_API_KEY"' ); } // Configure a Genkit instance. const ai = genkit({ plugins: [googleAI()], model: gemini20Flash, // set default model }); const { text } = await ai.generate(prompt); return ( <div className="restaurant__review_summary"> <p>{text}</p> <p>✨ Summarized with Gemini</p> </div> ); } catch (e) { console.error(e); return <p>Error summarizing reviews.</p>; } } - Erstellen Sie einen Commit mit der Commit-Nachricht „Use AI to summarize reviews“ und übertragen Sie ihn per Push in Ihr GitHub-Repository.
git add . git commit -m "Use AI to summarize reviews" git push - Öffnen Sie die Seite „App Hosting“ in der Firebase Console und warten Sie, bis der neue Roll-out abgeschlossen ist.
- Öffnen Sie die Seite eines Restaurants. Oben sollte eine Zusammenfassung aller Rezensionen auf der Seite in einem Satz angezeigt werden.
- Fügen Sie eine neue Rezension hinzu und aktualisieren Sie die Seite. Die Zusammenfassung sollte sich ändern.
11. Veröffentlichung Ihrer App-Hosting-Website aufheben
Wenn Sie die App nach Abschluss dieses Codelabs nicht weiter verwenden möchten, können Sie die Veröffentlichung aufheben, damit niemand auf Ihre Firestore-, Storage- und Gemini-Ressourcen zugreifen kann. Du kannst die Publikation jederzeit wieder veröffentlichen.
So heben Sie die Veröffentlichung einer App Hosting-Website auf:
- Öffnen Sie App Hosting in der Firebase Console.
- Suchen Sie das Backend Ihrer Anwendung und klicken Sie auf Ansehen.
- Klicken Sie im Abschnitt Backend-Informationen neben Domains auf Verwalten. Dadurch wird die Seite Domains geladen.
- Klicken Sie neben Ihrer Domain auf das Dreipunkt-Menü, wählen Sie Domain deaktivieren aus und klicken Sie dann zur Bestätigung auf Deaktivieren.
12. Fazit
Glückwunsch! Sie haben gelernt, wie Sie mit Firebase einer Next.js-Anwendung Features und Funktionen hinzufügen. Konkret haben Sie Folgendes verwendet:
- Firebase App Hosting, um Ihren Next.js-Code automatisch zu erstellen und bereitzustellen, wenn Sie ihn in einen konfigurierten Branch übertragen.
- Firebase Authentication, um die An- und Abmeldefunktion zu aktivieren.
- Cloud Firestore für Restaurantdaten und Daten zu Restaurantrezensionen.
- Cloud Storage for Firebase für Restaurantbilder.