1. Hinweis
In diesem Codelab erfahren Sie, wie Sie Firebase in eine Next.js-Web-App namens Friendly Eats integrieren. Dabei handelt es sich um eine Website für Restaurantrezensionen.
Die fertige Web-App bietet nützliche Funktionen, die zeigen, wie Firebase Ihnen beim Erstellen von Next.js-Apps helfen 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:Mit der fertigen Webanwendung können Sie sich mit Google anmelden und abmelden. Nutzer-Log‑ins und ‑Persistenz werden vollständig über Firebase Authentication verwaltet.
- Bilder:In der fertigen Web-App können angemeldete Nutzer Restaurantbilder 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 von Restaurants in Form einer Sternebewertung und einer Textnachricht posten. 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 Next.js-App-Router und serverseitigem Rendering verwenden
- Bilder in Cloud Storage for Firebase speichern
- So lesen und schreiben Sie Daten in einer Cloud Firestore-Datenbank.
- So verwenden Sie die Anmeldung mit Google mit dem Firebase JavaScript SDK.
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
- Sie können Ihr Firebase-Projekt auf den Blaze-Tarif upgraden.
2. Entwicklungsumgebung und GitHub-Repository einrichten
Dieses Codelab enthält den Starter-Code der App und basiert auf der Firebase CLI.
GitHub-Repository erstellen
Den Quellcode für das Codelab 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-start
abzurufen:npx giget@latest gh:firebase/friendlyeats-web/nextjs-start#master . --install
- Änderungen lokal mit Git nachverfolgen:
git init git add . git commit -m "codelab starting point" git branch -M main
- Erstellen Sie ein neues GitHub-Repository: https://github.com/new. Sie können ihm einen beliebigen Namen geben.
- Kopieren Sie die neue URL, die GitHub für Sie erstellt. Sie sieht so aus:
https://github.com/<USER_NAME>/<REPOSITORY_NAME>.git
odergit@github.com:<USER_NAME>/<REPOSITORY_NAME>.git
- Übertragen Sie lokale Ä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
- Jetzt sollte der Startcode 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
Y
oderN
ein, je nachdem, ob Firebase Daten erheben soll. - Wählen Sie in Ihrem Browser Ihr Google-Konto aus und klicken Sie dann 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 in der Firebase-Konsole mit demselben Google-Konto an, das Sie im vorherigen Schritt verwendet haben.
- Klicken Sie auf die Schaltfläche, um ein neues Projekt zu erstellen, und geben Sie dann einen Projektnamen ein (z. B.
FriendlyEats Codelab
).
- Klicken Sie auf Weiter.
- Lesen und akzeptieren Sie bei Aufforderung die Firebase-Nutzungsbedingungen 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 kein Google Analytics. 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 den Blaze-Tarif (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, können Sie prüfen, 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 durchführen, fragen Sie den Organisator, ob Cloud-Guthaben verfügbar ist.
So führen Sie für Ihr Projekt ein Upgrade auf den Tarif „Blaze“ durch:
- Wählen Sie in der Firebase Console die Option zum Upgraden Ihres Abos 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 zur Firebase-Konsole zurückkehren, um das Upgrade abzuschließen.
Web-App zu Ihrem Firebase-Projekt hinzufügen
- Rufen Sie in Ihrem Firebase-Projekt die Projektübersicht auf und klicken Sie dann auf
Web.
Wenn in Ihrem Projekt bereits Apps registriert sind, klicken Sie auf App hinzufügen, um das Websymbol zu sehen. - Geben Sie im Textfeld App-Nickname einen einprägsamen App-Nickname 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
- Rufen Sie in der Firebase Console Authentifizierung auf.
- Klicken Sie auf Jetzt starten.
- Klicken Sie in der Spalte Zusätzliche Anbieter 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 Build und wählen Sie dann Firestore-Datenbank aus.
- Klicken Sie auf Datenbank erstellen.
- Belassen Sie die Database ID (Datenbank-ID) auf
(default)
. - Wählen Sie einen Speicherort für Ihre Datenbank aus und klicken Sie auf Weiter.
Für eine echte App sollten Sie einen Speicherort auswählen, der sich in der Nähe Ihrer Nutzer befindet. - 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 öffentlich, 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 standardmäßigen Storage-Bucket aus.
Für Buckets inUS-WEST1
,US-CENTRAL1
undUS-EAST1
kann die kostenlose Stufe für Google Cloud Storage genutzt werden. 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. Veröffentlichen Sie keine App öffentlich, ohne Sicherheitsregeln für Ihren Storage-Bucket hinzuzufügen. - Klicken Sie auf Erstellen.
Sicherheitsregeln bereitstellen
Der Code enthält bereits Gruppen von 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 CLI, um das Firebase-Projekt zu verwenden, das Sie zuvor erstellt haben:
Geben Sie bei Aufforderungfirebase use --add
friendlyeats-codelab
als Alias ein. - Führen Sie den folgenden Befehl in Ihrem Terminal aus, um diese Sicherheitsregeln (sowie Indexe, die später benötigt werden) 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 des Starter-Codes der App an, denen Sie in diesem Codelab Funktionen hinzufügen.
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, Kopfzeilen, Restaurantdetails und Rezensionen |
| Hilfsfunktionen, 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 App ist eine Next.js-Webanwendung, die den App Router verwendet. Serverseitiges Rendering wird in der gesamten App verwendet. Die Datei src/app/page.js
ist beispielsweise eine Serverkomponente, die für die Hauptseite zuständig 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";
In der App wird das Symbol @
verwendet, um umständliche 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
. Die einzelnen React-Komponenten importieren die umschlossenen Funktionen dann aus dem Verzeichnis src/lib/firebase
, anstatt Firebase-Funktionen direkt zu importieren.
Simulierte Daten
Die Datei src/lib/randomData.js
enthält Mock-Daten für Restaurants und Rezensionen. 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 Branch in Ihrem Git-Repository zu beobachten.
Am Ende dieses Abschnitts haben Sie ein App Hosting-Backend, das mit Ihrem Repository in GitHub verbunden ist. Es wird automatisch neu erstellt und eine neue Version Ihrer App wird bereitgestellt, wenn Sie einen neuen Commit in Ihren main
-Branch übertragen.
Backend erstellen
- Rufen Sie in der Firebase Console die Seite App Hosting auf:
- Klicken Sie auf „Jetzt starten“, um den Erstellungsvorgang für das Back-End zu starten. Konfigurieren Sie Ihr Backend so:
- Wählen Sie eine Region aus. Bei einer echten App würden Sie die Region auswählen, die Ihren Nutzern am nächsten ist.
- Folgen Sie der Anleitung im Schritt „GitHub-Repository importieren“, um das GitHub-Repository zu verbinden, das Sie zuvor erstellt haben.
- Bereitstellungseinstellungen festlegen:
- Behalten Sie das Stammverzeichnis als
/
bei. - Stelle den Live-Zweig auf
main
ein. - Automatische Roll-outs aktivieren
- Behalten Sie das Stammverzeichnis als
- Benennen Sie das Backend mit
friendlyeats-codelab
. - Klicken Sie unter „Firebase-Web-App verknüpfen“ auf „Neue Firebase-Web-App erstellen“.
- Klicken Sie auf „Fertigstellen und bereitstellen“. Nach kurzer Zeit werden Sie zu einer neuen Seite weitergeleitet, auf der Sie den Status Ihres neuen App Hosting-Back-Ends sehen können.
- Klicken Sie nach Abschluss der Einführung unter „Domains“ auf Ihre kostenlose Domain. Es kann einige Minuten dauern, bis die Änderungen aufgrund der DNS-Weitergabe wirksam werden.
- Hoppla! Beim Laden der Seite wird die Fehlermeldung „Anwendungsfehler: Es ist eine serverseitige Ausnahme aufgetreten (weitere Informationen finden Sie in den Serverlogs).“ angezeigt.
- Sehen Sie in der Firebase Console auf dem Tab „Logs“ (Protokolle) Ihres App Hosting-Backends nach. Sie sehen ein Log mit dem Hinweis „Error: not implemented“ (Fehler: nicht implementiert). Das beheben wir im nächsten Schritt, wenn wir die Authentifizierung hinzufügen.
Sie haben die erste Web-App bereitgestellt. Jedes Mal, wenn Sie einen neuen Commit in den main
-Branch Ihres GitHub-Repositorys übertragen, wird in der Firebase-Konsole ein neuer Build und Roll-out gestartet. Ihre Website wird automatisch aktualisiert, sobald der Roll-out abgeschlossen ist.
6. Authentifizierung zur Web-App hinzufügen
In diesem Abschnitt fügen Sie der Web-App die Authentifizierung hinzu, damit Sie sich 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 des App-Hosting-Back-Ends zur Liste der genehmigten Domains in Ihrem Projekt hinzu.
- Kopieren Sie die Domain Ihres App Hosting-Backends von der Seite „Übersicht“ von App Hosting.
- Rufen Sie den Tab Auth Settings auf und wählen Sie Authorized Domains (Autorisierte Domains) aus.
- Klicken Sie auf Domain hinzufügen.
- Geben Sie die Domain Ihres App Hosting-Backends ein.
- Klicken Sie auf Hinzufügen.
An- und Abmeldefunktionen implementieren
- Ersetzen Sie in der Datei
src/lib/firebase/auth.js
die FunktionenonAuthStateChanged
,onIdTokenChanged
,signInWithGoogle
undsignOut
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 Observer für Änderungen am Anmeldestatus des Nutzers hinzu. | |
Fügt einen Observer für Änderungen am ID-Token des Nutzers hinzu. | |
Erstellt eine Instanz des Google-Authentifizierungsanbieters. | |
Startet einen dialogbasierten Authentifizierungsvorgang. | |
Meldet den Nutzer ab. |
Im Code der Datei src/components/Header.jsx
werden die Funktionen signInWithGoogle
und signOut
bereits aufgerufen.
Authentifizierungsstatus an den Server senden
Um den Authentifizierungsstatus an den Server zu übergeben, verwenden wir Cookies. Immer wenn sich der Authentifizierungsstatus im Client ändert, aktualisieren wir das __session
-Cookie.
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
Im Root-Layout in der Datei src/app/layout.js
wird der Header gerendert und der Nutzer, falls verfügbar, als Attribut übergeben.
<Header initialUser={currentUser?.toJSON()} />
Das bedeutet, dass die Komponente <Header>
Nutzerdaten, sofern verfügbar, während der Serverlaufzeit rendert. Wenn während des Seitenlebenszyklus nach dem ersten Seitenaufbau Authentifizierungsaktualisierungen erfolgen, werden diese vom onAuthStateChanged
-Handler verarbeitet.
Jetzt ist es an der Zeit, einen neuen Build bereitzustellen und zu überprüfen, was Sie erstellt haben.
- Erstellen Sie einen Commit mit der Commit-Nachricht „Add authentication“ (Authentifizierung hinzufügen) und übertragen Sie ihn per Push an Ihr GitHub-Repository.
- Öffnen Sie in der Firebase Console die App Hosting-Seite und warten Sie, bis die neue Bereitstellung abgeschlossen ist.
- Neues Authentifizierungsverhalten überprüfen:
- Aktualisieren Sie die Web-App in Ihrem Browser. Ihr Anzeigename wird im Header angezeigt.
- Melden Sie sich ab und wieder an. Sie können diesen Schritt mit verschiedenen Nutzern wiederholen.
- Optional: Klicken Sie mit der rechten Maustaste auf die Webanwendung, wählen Sie Seitenquelltext anzeigen aus und suchen Sie nach dem Anzeigenamen. Es ist im Roh-HTML-Quellcode enthalten, der vom Server zurückgegeben wird.
7. Restaurantinformationen ansehen
Die Web-App enthält Beispieldaten für Restaurants und Rezensionen.
Ein oder mehrere Restaurants hinzufügen
So fügen Sie Mock-Restaurantdaten in Ihre lokale Cloud Firestore-Datenbank ein:
- Melden Sie sich in der Web-App an, falls noch nicht geschehen. Wählen Sie dann
> Beispielrestaurants hinzufügen aus.
- Wählen Sie in der Firebase Console auf der Seite Firestore-Datenbank die Option restaurants aus. Sie sehen die Dokumente der obersten Ebene in der Sammlung „Restaurants“, die jeweils ein Restaurant repräsentieren.
- Klicken Sie auf einige Dokumente, um die Attribute eines Restaurantdokuments zu sehen.
Liste der Restaurants anzeigen
Ihre Cloud Firestore-Datenbank enthält jetzt Restaurants, die in der Next.js-Web-App angezeigt werden können.
So definieren Sie den Code zum Abrufen von Daten:
- Suchen Sie in der Datei
src/app/page.js
nach der Serverkomponente<Home />
und sehen Sie sich den Aufruf der FunktiongetRestaurants
an, mit der zur Laufzeit des Servers eine Liste von Restaurants abgerufen wird. In den folgenden Schritten implementieren Sie die FunktiongetRestaurants
. - Ersetzen Sie in der Datei
src/lib/firebase/firestore.js
die FunktionenapplyQueryFilters
undgetRestaurants
durch 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“ (Liste der Restaurants aus Firestore lesen) und übertragen Sie ihn per Push in Ihr GitHub-Repository.
- Öffnen Sie in der Firebase Console die App Hosting-Seite und warten Sie, bis die neue Bereitstellung abgeschlossen ist.
- Aktualisieren Sie die Seite in der Webanwendung. Restaurantbilder werden als Kacheln auf der Seite angezeigt.
Prüfen, ob die Restaurantinformationen beim Ausführen des Servers 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 Restaurant-Einträge zur Serverlaufzeit geladen werden:
- Öffnen Sie in der Web-App die Entwicklertools und deaktivieren Sie JavaScript.
- Aktualisieren Sie die Web-App. Die Restaurantinformationen werden weiterhin geladen. Restaurantinformationen werden in der Serverantwort zurückgegeben. Wenn JavaScript aktiviert ist, werden die Restaurantinformationen über den clientseitigen JavaScript-Code bereitgestellt.
- Aktivieren Sie JavaScript in den Entwicklertools wieder.
Mit Cloud Firestore-Snapshot-Listenern auf Restaurantaktualisierungen warten
Im vorherigen Abschnitt haben Sie gesehen, wie die erste Gruppe von Restaurants aus der Datei src/app/page.js
geladen wurde. 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 serverseitig gerendertes Markup rehydriert wird.
So konfigurieren Sie die Datei src/components/RestaurantListings.jsx
, um serverseitig gerendertes Markup zu rehydrieren:
- Sehen Sie sich in der Datei
src/components/RestaurantListings.jsx
den folgenden Code an, der bereits für Sie geschrieben wurde:
useEffect(() => {
return getRestaurantsSnapshot((data) => {
setRestaurants(data);
}, filters);
}, [filters]);
Mit diesem Code wird die Funktion getRestaurantsSnapshot()
aufgerufen, 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.js
die 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);
});
}
Änderungen, die über die Seite Firestore Database vorgenommen werden, werden jetzt in Echtzeit in der Web-App angezeigt.
- Erstellen Sie einen Commit mit der Commit-Nachricht „Listen for realtime restaurant updates“ (Echtzeit-Restaurantaktualisierungen abrufen) und übertragen Sie ihn per Push in Ihr GitHub-Repository.
- Öffnen Sie in der Firebase Console die App Hosting-Seite und warten Sie, bis die neue Bereitstellung abgeschlossen ist.
- Wählen Sie in der Web-App
> Beispielrestaurants hinzufügen aus. Wenn die Snapshot-Funktion richtig implementiert ist, werden die Restaurants in Echtzeit ohne Seitenaktualisierung angezeigt.
8. Von Nutzern eingereichte Rezensionen aus der Web-App speichern
- Ersetzen Sie in der Datei
src/lib/firebase/firestore.js
die 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. Der Code aktualisiert auch das vorhandene Firestore-Dokument, das das Restaurant repräsentiert, mit aktualisierten Zahlen für die Anzahl der Bewertungen und die durchschnittliche berechnete Bewertung.
- 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 der Formularübermittlung abzurufen.
So verwenden Sie eine Next.js-Serveraktion, um das eingereichte Rezensionsformular zu verarbeiten:
- Suchen Sie in der Datei
src/components/ReviewDialog.jsx
im Element<form>
nach dem Attributaction
.
<form action={handleReviewFormSubmission}>
Der Attributwert action
verweist auf eine Funktion, die Sie im nächsten Schritt implementieren.
- Ersetzen Sie in der Datei
src/app/actions.js
die FunktionhandleReviewFormSubmission()
durch den folgenden Code:
// This is a next.js server action, which is an alpha feature, so
// use with caution.
// https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions
export async function handleReviewFormSubmission(data) {
const { app } = await getAuthenticatedAppForUser();
const db = getFirestore(app);
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 Rezensionseinsendungen implementiert. Jetzt können Sie überprü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 ein Commit mit der Commit-Nachricht „Allow users to submit restaurant reviews“ (Nutzern erlauben, Restaurantrezensionen einzureichen) und übertragen Sie es per Push an Ihr GitHub-Repository.
- Öffnen Sie in der Firebase Console die App Hosting-Seite und warten Sie, bis die neue Bereitstellung 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 überprüfen möchten, um zu bestätigen, dass es wie erwartet eingefügt wurde.
9. Von Nutzern hochgeladene Dateien aus der Web-App speichern
In diesem Abschnitt fügen Sie Funktionen hinzu, mit denen Sie das Bild eines Restaurants 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 repräsentiert.
So speichern Sie von Nutzern hochgeladene Dateien aus der Web-App:
- Sehen Sie sich in der Datei
src/components/Restaurant.jsx
den 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 sind keine Änderungen erforderlich. Das Verhalten der updateRestaurantImage()
-Funktion wird in den folgenden Schritten implementiert.
- Ersetzen Sie in der Datei
src/lib/firebase/storage.js
die 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 die Bilder wie erwartet hochgeladen werden:
- Erstellen Sie einen Commit mit der Commit-Nachricht „Allow users to change each restaurants' photo“ (Nutzern erlauben, das Foto jedes Restaurants zu ändern) und übertragen Sie ihn per Push in Ihr GitHub-Repository.
- Öffnen Sie in der Firebase Console die App Hosting-Seite und warten Sie, bis die neue Bereitstellung abgeschlossen ist.
- Prüfen Sie, ob Sie in der Web-App angemeldet sind, und wählen Sie ein Restaurant aus.
- Klicken Sie auf
und laden Sie ein Bild aus Ihrem Dateisystem hoch. Ihr Bild verlässt Ihre lokale Umgebung und wird in Cloud Storage hochgeladen. Das Bild wird sofort nach dem Hochladen angezeigt.
- Rufen Sie Cloud Storage für Firebase auf.
- Rufen Sie den Ordner auf, der das Restaurant repräsentiert. Das von Ihnen hochgeladene Bild ist im Ordner vorhanden.
10. Restaurantrezensionen mit generativer KI zusammenfassen
In diesem Abschnitt fügen Sie eine Funktion für die Zusammenfassung von Rezensionen 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“.
- Wählen Sie in der Eingabeaufforderung „Google Cloud-Projekte durchsuchen“ Ihr Firebase-Projekt aus. Jedes Firebase-Projekt basiert auf einem Google Cloud-Projekt.
- 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 „Production“ (Produktion) aus.
- Wenn Sie gefragt werden, ob Sie den 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.yaml
hinzugefügt werden soll, geben SieY
ein, um die Frage zu bejahen.
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 die Rezensionszusammenfassung implementieren
- Ersetzen Sie in
src/components/Reviews/ReviewSummary.jsx
die FunktionGeminiSummary
durch 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://firebase.google.com/docs/genkit/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“ (KI zum Zusammenfassen von Rezensionen verwenden) und übertragen Sie ihn per Push an Ihr GitHub-Repository.
- Öffnen Sie in der Firebase Console die App Hosting-Seite und warten Sie, bis die neue Bereitstellung abgeschlossen ist.
- Öffnen Sie die Seite eines Restaurants. Oben auf der Seite sehen Sie eine Zusammenfassung aller Rezensionen auf der Seite in einem Satz.
- Fügen Sie eine neue Rezension hinzu und aktualisieren Sie die Seite. Die Zusammenfassung der Änderung sollte angezeigt werden.
11. Fazit
Glückwunsch! Sie haben gelernt, wie Sie Firebase verwenden, um einer Next.js-App Funktionen hinzuzufügen. Insbesondere 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 An- und Abmeldefunktionen zu aktivieren.
- Cloud Firestore für Restaurantdaten und Daten zu Restaurantrezensionen.
- Cloud Storage for Firebase für Restaurantbilder.