Firebase'i Next.js uygulamasıyla entegre etme

1. Başlamadan önce

Bu codelab'de, restoran değerlendirmelerine yönelik bir web sitesi olan Friendly Eats adlı Next.js web uygulamasıyla Firebase'i nasıl entegre edeceğinizi öğreneceksiniz.

Friendly Eats web uygulaması

Tamamlanmış web uygulaması, Firebase'in Next.js uygulamalarını geliştirmenize nasıl yardımcı olabileceğini gösteren faydalı özellikler sunuyor. Bu özellikler arasında şunlar bulunur:

  • Otomatik derleme ve dağıtım: Bu codelab'de, yapılandırılmış bir dala her aktarma yaptığınızda Next.js kodunuzu otomatik olarak oluşturmak ve dağıtmak için Firebase App Hosting kullanılır.
  • Oturum açma ve oturumu kapatma: Tamamlanmış web uygulaması, Google ile oturum açmanıza ve oturumu kapatmanıza olanak tanır. Kullanıcı girişi ve kalıcılığı tamamen Firebase Authentication üzerinden yönetilir.
  • Görseller: Tamamlanmış web uygulaması, oturum açmış kullanıcıların restoran resimleri yüklemesine olanak tanır. Resim öğeleri, Firebase için Cloud Storage'da depolanır. Firebase JavaScript SDK'sı, yüklenen resimler için herkese açık bir URL sağlar. Daha sonra bu herkese açık URL, Cloud Firestore'daki ilgili restoran dokümanında saklanır.
  • Yorumlar: Tamamlanmış web uygulaması, oturum açmış kullanıcıların yıldız puanı ve metin tabanlı bir mesajdan oluşan restoranlar hakkında yorum yayınlamasına olanak tanır. İnceleme bilgileri Cloud Firestore'da saklanır.
  • Filtreler: Tamamlanmış web uygulaması, oturum açmış kullanıcıların restoran listesini kategori, konum ve fiyata göre filtrelemesine olanak tanır. Kullanılan sıralama yöntemini de özelleştirebilirsiniz. Verilere Cloud Firestore'dan erişilir ve Firestore sorguları, kullanılan filtrelere göre uygulanır.

Ön koşullar

  • GitHub hesabı
  • Next.js ve JavaScript bilgisi

Neler öğreneceksiniz?

  • Firebase'i Next.js uygulama yönlendirici ve sunucu tarafı oluşturma ile kullanma.
  • Cloud Storage for Firebase'de görüntülerin nasıl kalıcı hale getirileceği.
  • Cloud Firestore veritabanında veri okuma ve yazma.
  • Firebase JavaScript SDK ile Google ile oturum açma özelliğini kullanma

Gerekenler

  • Git
  • Node.js'nin son kararlı sürümü
  • Tercih ettiğiniz bir tarayıcı (ör. Google Chrome)
  • Kod düzenleyici ve terminal bulunan geliştirme ortamı
  • Firebase projenizin oluşturulması ve yönetilmesi için bir Google hesabı
  • Firebase projenizi Blaze fiyatlandırma planına yükseltme olanağı

2. Geliştirme ortamınızı ve GitHub deponuzu ayarlama

Bu codelab, uygulamanın başlangıç kod tabanını sağlar ve Firebase CLI'yı kullanır.

GitHub deposu oluşturma

codelab'i https://github.com/firebase/Friendlyeats-web adresinde bulabilirsiniz. Depo, birden fazla platform için örnek projeler içerir. Ancak bu codelab yalnızca nextjs-start dizinini kullanır. Aşağıdaki dizinlere dikkat edin:

* `nextjs-start`: contains the starter code upon which you build.
* `nextjs-end`: contains the solution code for the finished web app.

nextjs-start klasörünü kendi deponuza kopyalayın:

  1. Terminal kullanarak bilgisayarınızda yeni bir klasör oluşturun ve bu klasörü yeni dizinde değiştirin:
    mkdir codelab-friendlyeats-web
    
    cd codelab-friendlyeats-web
    
  2. Yalnızca nextjs-start klasörünü getirmek için giget npm paketini kullanın:
    npx giget@latest gh:firebase/friendlyeats-web/nextjs-start#master . --install
    
  3. Git ile değişiklikleri yerel olarak izleyin:
    git init
    
    git commit -a -m "codelab starting point"
    
    git branch -M main
    
  4. Yeni bir GitHub deposu oluşturun: https://github.com/new. İstediğiniz adı verin.
    1. GitHub size https://github.com//.git veya git@github.com:/.git şeklinde görünen yeni bir kod deposu URL'si verir. Bu URL'yi kopyalayın.
  5. Yerel değişiklikleri yeni GitHub deponuza aktarın. Depo URL'nizi yer tutucusuyla değiştirerek aşağıdaki komutu çalıştırın.
    git remote add origin <your-repository-url>
    
    git push -u origin main
    
  6. Başlangıç kodunu GitHub deponuzda görmeniz gerekir.

Firebase CLI'ı yükleme veya güncelleme

Firebase CLI'nin yüklü olduğunu ve bu sürümün 13.9.0 veya sonraki bir sürüm olduğunu doğrulamak için aşağıdaki komutu çalıştırın:

firebase --version

Daha düşük bir sürüm görürseniz veya Firebase CLI yüklü değilse yükleme komutunu çalıştırın:

npm install -g firebase-tools@latest

İzin hataları nedeniyle Firebase CLI'ı yükleyemiyorsanız npm dokümanlarına bakın veya başka bir yükleme seçeneğini kullanın.

Firebase'e giriş yapma

  1. Firebase CLI'ya giriş yapmak için aşağıdaki komutu çalıştırın:
    firebase login
    
  2. Firebase'in veri toplamasını isteyip istemediğinize bağlı olarak Y veya N girin.
  3. Tarayıcınızda Google hesabınızı seçin, ardından İzin ver'i tıklayın.

3. Firebase projenizi oluşturun

Bu bölümde bir Firebase projesi oluşturacaksınız ve Firebase web uygulamasını bu projeyle ilişkilendireceksiniz. Örnek web uygulaması tarafından kullanılan Firebase hizmetlerini de kuracaksınız.

Firebase projesi oluşturma

  1. Firebase konsolunda Proje ekle'yi tıklayın.
  2. Projenizin adını girin metin kutusuna FriendlyEats Codelab (veya tercih ettiğiniz bir proje adı) yazın ve ardından Devam'ı tıklayın.
  3. Firebase faturalandırma planını onaylayın iletişim kutusunda planın Blaze olduğunu onaylayın ve ardından Planı onayla'yı tıklayın.
  4. Bu codelab için Google Analytics'e ihtiyacınız yoktur. Bu nedenle Bu proje için Google Analytics'i etkinleştir seçeneğini kapalı konuma getirin.
  5. Create project (Proje oluştur) seçeneğini tıklayın.
  6. Projenizin temel hazırlığını yapmasını bekleyin ve ardından Devam'ı tıklayın.
  7. Firebase projenizde Proje Ayarları'na gidin. Daha sonra ihtiyacınız olacağından proje kimliğinizi not edin. Bu benzersiz tanımlayıcı, projenizin tanımlanma şeklidir (örneğin, Firebase CLI'da).

Firebase fiyatlandırma planınızı yükseltin

Uygulama Barındırma'yı kullanmak için Firebase projenizin Blaze fiyatlandırma planı kapsamında olması gerekir, yani bir Cloud Faturalandırma Hesabı ile ilişkilendirilmiş olmalıdır.

  • Cloud Faturalandırma hesabı için kredi kartı gibi bir ödeme yöntemi gerekir.
  • Firebase ve Google Cloud'u kullanmaya yeni başladıysanız 300 ABD doları kredi ve Ücretsiz Deneme Cloud Faturalandırma Hesabı için uygun olup olmadığınızı kontrol edin.

Projenizi Blaze planına yükseltmek için aşağıdaki adımları izleyin:

  1. Firebase konsolunda planınızı yükseltmeyi seçin.
  2. İletişim kutusunda Blaze planını seçin, ardından projenizi bir Cloud Faturalandırma Hesabı ile ilişkilendirmek için ekrandaki talimatları uygulayın.
    Cloud Faturalandırma Hesabı oluşturmanız gerekiyorsa yükseltmeyi tamamlamak için Firebase konsolunda yükseltme akışına geri dönmeniz gerekebilir.

Firebase projenize web uygulaması ekleyin

  1. Firebase projenizde Projeye genel bakış'a gidin ve ardından e41f2efdd9539c31.png Web'i tıklayın.

    Projenizde kayıtlı uygulamalar varsa web simgesini görmek için Uygulama ekle'yi tıklayın.
  2. Uygulama takma adı metin kutusuna My Next.js app gibi akılda kalıcı bir uygulama takma adı girin.
  3. Bu uygulama için Firebase Hosting'i de kur onay kutusunun işaretini kaldırın.
  4. Uygulamayı kaydet > Sonraki > Sonraki > Konsola devam et.

Firebase konsolunda Firebase hizmetlerini ayarlama

Kimlik doğrulamayı ayarlama

  1. Firebase konsolunda Kimlik Doğrulama'ya gidin.
  2. Başlayın'ı tıklayın.
  3. Ek sağlayıcılar sütununda Google > Etkinleştir'i tıklayın.
  4. Proje için herkese açık ad metin kutusuna My Next.js app gibi akılda kalıcı bir ad girin.
  5. Proje için destek e-posta adresi açılır menüsünden e-posta adresinizi seçin.
  6. Kaydet'i tıklayın.

Cloud Firestore'u kurma

  1. Firebase konsolunda Firestore'a gidin.
  2. Create database > (Veritabanı oluştur) > Sonraki > Test modunda başlat > Sıradaki adım.
    Bu codelab'in ilerleyen bölümlerinde, verilerinizin güvenliğini sağlamak için Güvenlik Kuralları ekleyeceksiniz. Veritabanınız için Güvenlik Kuralları eklemeden bir uygulamayı herkese açık şekilde dağıtmayın veya kullanıma açık hale getirmeyinyapmayın uygulamayı herkese açık olarak dağıtmayın veya açığa çıkarmayın
  3. Varsayılan konumu kullanın veya istediğiniz bir konumu seçin.
    Gerçek bir uygulama için kullanıcılarınıza yakın bir konum seçmek istersiniz. Bu konumun daha sonra değiştirilemeyeceğini ve otomatik olarak varsayılan Cloud Storage paketinizin konumu olacağını unutmayın (sonraki adım).
  4. Bitti'yi tıklayın.

Firebase için Cloud Storage'ı kurma

  1. Firebase konsolunda Storage'a gidin.
  2. Başlayın > Test modunda başlat > Sıradaki adım.
    Bu codelab'in ilerleyen bölümlerinde, verilerinizin güvenliğini sağlamak için Güvenlik Kuralları ekleyeceksiniz. Depolama paketiniz için Güvenlik Kuralları eklemeden bir uygulamayı herkese açık şekilde dağıtmayın veya açığa çıkarmayınyapmayın uygulamayı herkese açık olarak dağıtmayın veya kullanıma sunmayın.
  3. Paketinizin konumu önceden seçilmiş olmalıdır (önceki adımda Firestore'un ayarlanması nedeniyle).
  4. Bitti'yi tıklayın.

4. Başlatıcı kod tabanını inceleme

Bu bölümde, bu codelab'deki işlevleri ekleyeceğiniz, uygulamanın başlangıç kod tabanındaki birkaç alanı inceleyeceksiniz.

Klasör ve dosya yapısı

Aşağıdaki tabloda, uygulamanın klasör ve dosya yapısına genel bir bakış yer almaktadır:

Klasörler ve dosyalar

Açıklama

src/components

Filtreler, başlıklar, restoran ayrıntıları ve yorumlarla ilgili bileşenlere tepki verme

src/lib

React veya Next.js'ye bağlı olması gerekmeyen yardımcı işlevler

src/lib/firebase

Firebase'e özel kod ve Firebase yapılandırması

public

Web uygulamasındaki simgeler gibi statik öğeler

src/app

Next.js Uygulama Yönlendiricisi ile yönlendirme

src/app/restaurant

API rota işleyici

package.json ve package-lock.json

npm ile proje bağımlılıkları

next.config.js

Next.js'ye özel yapılandırma (sunucu işlemleri etkin)

jsconfig.json

JavaScript dil hizmeti yapılandırması

Sunucu ve istemci bileşenleri

Uygulama, Uygulama Yönlendirici'yi kullanan bir Next.js web uygulamasıdır. Sunucu oluşturma işlemi uygulama genelinde kullanılır. Örneğin, src/app/page.js dosyası ana sayfadan sorumlu bir sunucu bileşenidir. src/components/RestaurantListings.jsx dosyası, dosyanın başındaki "use client" yönergesiyle belirtilen bir istemci bileşenidir.

İfadeleri içe aktar

Aşağıdaki gibi içe aktarma ifadeleri görebilirsiniz:

import RatingPicker from "@/src/components/RatingPicker.jsx";

Uygulama, kullanışsız göreli içe aktarma yollarından kaçınmak için @ simgesini kullanır ve yol takma adları ile mümkün olur.

Firebase'e özel API'ler

Tüm Firebase API kodları, src/lib/firebase dizininde sarmalanır. Ardından her bir React bileşenleri, Firebase işlevlerini doğrudan içe aktarmak yerine sarmalanmış işlevleri src/lib/firebase dizininden içe aktarır.

Sahte veriler

Sahte restoran ve yorum verileri src/lib/randomData.js dosyasında yer alıyor. Bu dosyadaki veriler src/lib/fakeRestaurants.js dosyasındaki kodda birleştirilir.

5. Uygulama Barındırma arka ucu oluşturma

Bu bölümde, git deponuzdaki bir dalı izlemek için Uygulama Barındırma arka ucu oluşturacaksınız.

Bu bölümün sonunda GitHub'daki deponuza bağlı bir App Hosting arka ucunuz olacak. Bu arka ucunuz, main dalınıza yeni kayıt aktardığınızda uygulamanızın yeni sürümünü otomatik olarak yeniden oluşturup kullanıma sunacaktır.

Güvenlik Kurallarını Dağıtma

Bu kodda zaten Firestore ve Cloud Storage for Firebase için güvenlik kuralı grupları vardır. Güvenlik Kuralları'nı dağıttıktan sonra veritabanınızdaki ve paketinizdeki veriler kötüye kullanıma karşı daha iyi korunur.

  1. Terminalinizde, CLI'yı daha önce oluşturduğunuz Firebase projesini kullanacak şekilde yapılandırın:
    firebase use --add
    
    Takma ad istendiğinde friendlyeats-codelab yazın.
  2. Bu Güvenlik Kuralları'nı dağıtmak için terminalinizde şu komutu çalıştırın:
    firebase deploy --only firestore:rules,storage
    
  3. "Cloud Storage for Firebase needs an IAM Role to use cross-service rules. Grant the new role?" istemini alırsanız Enter tuşuna basarak Evet'i seçin.

Firebase yapılandırmanızı web uygulaması kodunuza ekleyin

  1. Firebase konsolunda Proje ayarları'na gidin.
  2. SDK kurulumu ve yapılandırması bölmesinde "Uygulama ekle"yi tıklayın ve yeni bir web uygulaması kaydetmek için kod parantezi simgesini tıklayın.
  3. Web uygulaması oluşturma akışının sonunda, firebaseConfig değişkenini, ardından özelliklerini ve değerlerini kopyalayın.
  4. Kod düzenleyicinizde apphosting.yaml dosyasını açın ve ortam değişkeni değerlerini Firebase konsolundaki yapılandırma değerleriyle doldurun.
  5. Dosyadaki mevcut özellikleri, kopyaladığınız özelliklerle değiştirin.
  6. Dosyayı kaydedin.

Arka uç oluşturma

  1. Firebase konsolunda Uygulama Barındırma sayfasına gidin:

Uygulama Barındırma konsolunun sıfır durumu ve &quot;Başlayın&quot; bölümü düğme

  1. "Başlayın"ı tıklayın arka uç oluşturma akışını başlatın. Arka ucunuzu aşağıdaki gibi yapılandırın:
  2. Daha önce oluşturduğunuz GitHub deposuna bağlanmak için ilk adımdaki talimatları uygulayın.
  3. Dağıtım ayarlarını belirleyin:
    1. Kök dizini / olarak tut
    2. Canlı dalı main olarak ayarla
    3. Otomatik kullanıma sunmayı etkinleştir
  4. Arka ucunuzu friendlyeats-codelab olarak adlandırın.
  5. "Firebase web uygulaması oluşturun veya ilişkilendirin" bölümünde, "Mevcut bir Firebase web uygulamasını seçin" bölümünden daha önce yapılandırdığınız web uygulamasını seçin. açılır.
  6. "Bitir ve dağıt"ı tıklayın. Kısa bir süre sonra yeni Uygulama Barındırma arka ucunuzun durumunu görebileceğiniz yeni bir sayfaya yönlendirilirsiniz.
  7. Kullanıma sunma işleminiz tamamlandıktan sonra "alanlar" bölümünde ücretsiz alan adınızı tıklayın. DNS yayılımı nedeniyle bu işlemin çalışmaya başlaması birkaç dakika sürebilir.

İlk web uygulamasını dağıttınız. GitHub deponuzun main dalına her yeni kayıt aktardığınızda, Firebase konsolunda yeni bir derleme ve kullanıma sunma işleminin başladığını görürsünüz. Kullanıma sunma işlemi tamamlandığında siteniz otomatik olarak güncellenir.

6. Web uygulamasına kimlik doğrulama ekleme

Bu bölümde, giriş yapabilmeniz için web uygulamasına kimlik doğrulaması eklersiniz.

Oturum açma ve çıkış yapma işlevlerini uygulama

  1. src/lib/firebase/auth.js dosyasında onAuthStateChanged, signInWithGoogle ve signOut işlevlerini aşağıdaki kodla değiştirin:
export function onAuthStateChanged(cb) {
	return _onAuthStateChanged(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);
  }
}

Bu kod aşağıdaki Firebase API'lerini kullanır:

Firebase API'si

Açıklama

GoogleAuthProvider

Google kimlik doğrulama sağlayıcı örneği oluşturur.

signInWithPopup

İletişim kutusu tabanlı bir kimlik doğrulama akışı başlatır.

auth.signOut

Kullanıcının oturumu kapatılır.

src/components/Header.jsx dosyasında, kod zaten signInWithGoogle ve signOut işlevlerini çağırır.

  1. "Add Google Authentication" (Google Kimlik Doğrulaması Ekleme) kayıt mesajıyla bir kayıt oluşturun kod deponuza gönderebilirsiniz. 1. Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
  2. Web uygulamasında sayfayı yenileyin ve Google ile oturum aç'ı tıklayın. Web uygulaması güncellenmediği için oturum açmanın başarılı olup olmadığı belirlenemiyor.

Sunucuya kimlik doğrulama durumunu gönder

Kimlik doğrulama durumunu sunucuya iletmek için bir hizmet çalışanı kullanacağız. fetchWithFirebaseHeaders ve getAuthIdToken işlevlerini aşağıdaki kodla değiştirin:

async function fetchWithFirebaseHeaders(request) {
  const app = initializeApp(firebaseConfig);
  const auth = getAuth(app);
  const installations = getInstallations(app);
  const headers = new Headers(request.headers);
  const [authIdToken, installationToken] = await Promise.all([
    getAuthIdToken(auth),
    getToken(installations),
  ]);
  headers.append("Firebase-Instance-ID-Token", installationToken);
  if (authIdToken) headers.append("Authorization", `Bearer ${authIdToken}`);
  const newRequest = new Request(request, { headers });
  return await fetch(newRequest);
}

async function getAuthIdToken(auth) {
  await auth.authStateReady();
  if (!auth.currentUser) return;
  return await getIdToken(auth.currentUser);
}

Sunucuda kimlik doğrulama durumunu okuma

İstemcinin kimlik doğrulama durumunu sunucuda yansıtmak için FirebaseServerApp'i kullanacağız.

src/lib/firebase/serverApp.js öğesini açın ve getAuthenticatedAppForUser işlevini değiştirin:

export async function getAuthenticatedAppForUser() {
  const idToken = headers().get("Authorization")?.split("Bearer ")[1];
  console.log('firebaseConfig', JSON.stringify(firebaseConfig));
  const firebaseServerApp = initializeServerApp(
    firebaseConfig,
    idToken
      ? {
          authIdToken: idToken,
        }
      : {}
  );

  const auth = getAuth(firebaseServerApp);
  await auth.authStateReady();

  return { firebaseServerApp, currentUser: auth.currentUser };
}

Kimlik doğrulama değişikliklerine abone ol

Kimlik doğrulama değişikliklerine abone olmak için aşağıdaki adımları uygulayın:

  1. src/components/Header.jsx dosyasına gidin.
  2. useUserSession işlevini aşağıdaki kodla değiştirin:
function useUserSession(initialUser) {
	// The initialUser comes from the server via a server component
	const [user, setUser] = useState(initialUser);
	const router = useRouter();

	// Register the service worker that sends auth state back to server
	// The service worker is built with npm run build-service-worker
	useEffect(() => {
		if ("serviceWorker" in navigator) {
			const serializedFirebaseConfig = encodeURIComponent(JSON.stringify(firebaseConfig));
			const serviceWorkerUrl = `/auth-service-worker.js?firebaseConfig=${serializedFirebaseConfig}`
		
		  navigator.serviceWorker
			.register(serviceWorkerUrl)
			.then((registration) => console.log("scope is: ", registration.scope));
		}
	  }, []);

	useEffect(() => {
		const unsubscribe = onAuthStateChanged((authUser) => {
			setUser(authUser)
		})

		return () => unsubscribe()
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, []);

	useEffect(() => {
		onAuthStateChanged((authUser) => {
			if (user === undefined) return

			// refresh when user changed to ease testing
			if (user?.email !== authUser?.email) {
				router.refresh()
			}
		})
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [user])

	return user;
}

Bu kod, onAuthStateChanged işlevi kimlik doğrulama durumunda bir değişiklik olduğunu belirttiğinde kullanıcıyı güncellemek için bir Tepki durumu kancası kullanır.

Değişiklikleri doğrulayın

src/app/layout.js dosyasındaki kök düzen, başlığı oluşturur ve varsa kullanıcıya özellik olarak iletir.

<Header initialUser={currentUser?.toJSON()} />

Bu durum, <Header> bileşeninin sunucu çalışma zamanı sırasında, varsa kullanıcı verilerini oluşturduğu anlamına gelir. İlk sayfa yüklemesinden sonra sayfa yaşam döngüsü boyunca herhangi bir kimlik doğrulama güncellemesi yapılırsa onAuthStateChanged işleyici bunları işler.

Şimdi yeni bir yapıyı kullanıma sunup oluşturduğunuzu doğrulama zamanı.

  1. "Oturum açma durumunu göster" kayıt mesajıyla bir kayıt oluşturun kod deponuza gönderebilirsiniz.
  2. Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
  3. Yeni kimlik doğrulama davranışını doğrulayın:
    1. Tarayıcınızda, web uygulamasını yenileyin. Görünen adınız başlıkta gösterilir.
    2. Oturumu kapatıp tekrar açın. Sayfa, sayfa yenilenmeden gerçek zamanlı olarak güncellenir. Bu adımı farklı kullanıcılarla tekrarlayabilirsiniz.
    3. İsteğe bağlı: Web uygulamasını sağ tıklayın, Sayfa kaynağını görüntüle'yi seçin ve görünen adı arayın. Sunucudan döndürülen ham HTML kaynağında görünür.

7. Restoran bilgilerini göster

Web uygulaması, restoranlar ve yorumlarla ilgili sahte veriler içerir.

Bir veya daha fazla restoran ekleyin

Yerel Cloud Firestore veritabanınıza örnek restoran verileri eklemek için şu adımları uygulayın:

  1. Web uygulamasında 2cf67d488d8e6332.png simgesini seçin > Örnek restoranlar ekleyin.
  2. Firestore Database sayfasındaki Firebase konsolunda restoranlar seçeneğini belirleyin. Restoran koleksiyonunda, her biri bir restoranı temsil eden üst düzey belgeleri görüyorsunuz.
  3. Bir restoran dokümanının özelliklerini keşfetmek için birkaç dokümanı tıklayın.

Restoranların listesini göster

Cloud Firestore veritabanınızda artık Next.js web uygulamasının gösterebileceği restoranlar bulunuyor.

Veri getirme kodunu tanımlamak için aşağıdaki adımları izleyin:

  1. src/app/page.js dosyasında <Home /> sunucu bileşenini bulun ve getRestaurants işlevine yönelik çağrıyı inceleyin. Bu işlev, sunucu çalışma zamanında restoran listesini alır. getRestaurants işlevini aşağıdaki adımlarda uygularsınız.
  2. src/lib/firebase/firestore.js dosyasında applyQueryFilters ve getRestaurants işlevlerini aşağıdaki kodla değiştirin:
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(),
		};
	});
}
  1. "Firestore'daki restoranların listesini oku" kayıt mesajıyla bir kayıt oluşturun kod deponuza gönderebilirsiniz.
  2. Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
  3. Web uygulamasında sayfayı yenileyin. Restoran resimleri sayfada karo olarak görünür.

Restoran girişlerinin sunucu çalışma zamanında yüklendiğini doğrulama

Next.js çerçevesi kullanılarak, verilerin sunucu çalışma zamanında veya istemci tarafı çalışma zamanında yüklendiği zaman anlaşılmayabilir.

Restoran girişlerinin sunucu çalışma zamanında yüklendiğini doğrulamak için aşağıdaki adımları izleyin:

  1. Web uygulamasında Geliştirici Araçları'nı açın ve JavaScript'i devre dışı bırakın.

Geliştirici Araçları&#39;nda JavaScript&#39;i devre dışı bırak

  1. Web uygulamasını yenileyin. Restoran girişleri yüklenmeye devam eder. Sunucu yanıtında restoran bilgileri döndürülür. JavaScript etkinleştirildiğinde restoran bilgileri, istemci taraflı JavaScript kodu aracılığıyla ortaya çıkarılır.
  2. Geliştirici Araçları'nda JavaScript'i yeniden etkinleştirin.

Cloud Firestore anlık görüntü dinleyicileriyle restoran güncellemelerini dinleyin

Önceki bölümde, ilk restoran grubunun src/app/page.js dosyasından nasıl yüklendiğini gördünüz. src/app/page.js dosyası bir sunucu bileşenidir ve Firebase veri getirme kodu dahil olmak üzere sunucuda oluşturulur.

src/components/RestaurantListings.jsx dosyası bir istemci bileşenidir ve sunucu tarafından oluşturulan işaretlemeyi karma hale getirmek üzere yapılandırılabilir.

src/components/RestaurantListings.jsx dosyasını, sunucu tarafından oluşturulan işaretlemeyi destekleyecek şekilde yapılandırmak için şu adımları uygulayın:

  1. src/components/RestaurantListings.jsx dosyasında, sizin için zaten yazılmış olan aşağıdaki kodu kontrol edin:
useEffect(() => {
        const unsubscribe = getRestaurantsSnapshot(data => {
                setRestaurants(data);
        }, filters);

        return () => {
                unsubscribe();
        };
}, [filters]);

Bu kod, önceki bir adımda uyguladığınız getRestaurants() işlevine benzeyen getRestaurantsSnapshot() işlevini çağırır. Ancak bu anlık görüntü işlevi, restoranın koleksiyonunda her değişiklik yapıldığında geri çağırma işlevinin çağrılması için bir geri çağırma mekanizması sağlar.

  1. src/lib/firebase/firestore.js dosyasında getRestaurantsSnapshot() işlevini aşağıdaki kodla değiştirin:
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);

	const unsubscribe = 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);
	});

	return unsubscribe;
}

Firestore Veritabanı sayfası üzerinden yapılan değişiklikler artık web uygulamasına gerçek zamanlı olarak yansıtılıyor.

  1. "Gerçek zamanlı restoran güncellemelerini dinle" kayıt mesajıyla bir kayıt oluşturun kod deponuza gönderebilirsiniz.
  2. Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
  3. Web uygulamasında 27ca5d1e8ed8adfe.png simgesini seçin > Örnek restoranlar ekleyin. Anlık görüntü işleviniz doğru bir şekilde uygulanırsa restoranlar sayfa yenilenmeden gerçek zamanlı olarak görünür.

8. Web uygulamasından kullanıcıların gönderdiği yorumları kaydetme

  1. src/lib/firebase/firestore.js dosyasında updateWithRating() işlevini aşağıdaki kodla değiştirin:
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()),
	});
};

Bu kod, yeni incelemeyi temsil eden yeni bir Firestore belgesi ekler. Kod ayrıca, restoranı temsil eden mevcut Firestore belgesini, puan sayısı ve hesaplanan ortalama puan için güncellenmiş rakamlarla günceller.

  1. addReviewToRestaurant() işlevini aşağıdaki kodla değiştirin:
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 Sunucu İşlemini Uygulama

Next.js Sunucu İşlemi, form verilerine erişmek için kullanışlı bir API sağlar. Örneğin, form gönderme yükünden metin değerini almak için data.get("text") gibi.

İnceleme formu gönderimini işlemek üzere bir Next.js Sunucu İşlemi kullanmak için aşağıdaki adımları uygulayın:

  1. src/components/ReviewDialog.jsx dosyasındaki <form> öğesinde action özelliğini bulun.
<form action={handleReviewFormSubmission}>

action özellik değeri, sonraki adımda uygulayacağınız bir işlevi ifade eder.

  1. src/app/actions.js dosyasında handleReviewFormSubmission() işlevini aşağıdaki kodla değiştirin:
// 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"),
        });
}

Bir restoranla ilgili yorum ekleme

İnceleme gönderimleri için destek uyguladınız. Artık yorumlarınızın Cloud Firestore'a doğru şekilde eklendiğini doğrulayabilirsiniz.

İnceleme eklemek ve incelemenin Cloud Firestore'a eklendiğini doğrulamak için şu adımları uygulayın:

  1. "Kullanıcıların restoran yorumları göndermesine izin ver" taahhüt mesajı içeren bir taahhüt oluşturun kod deponuza gönderebilirsiniz.
  2. Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
  3. Web uygulamasını yenileyin ve ana sayfadan bir restoran seçin.
  4. Restoranın sayfasında 3e19beef78bb0d0e.png'i tıklayın.
  5. Yıldız puanı seçin.
  6. Yorum yazın.
  7. Gönder'i tıklayın. Yorumunuz, yorum listesinin en üstünde görünür.
  8. Cloud Firestore'da, incelediğiniz restoranın belgesini Belge ekle bölmesinde arayın ve seçin.
  9. Koleksiyonu başlat bölmesinde derecelendirmeler'i seçin.
  10. Doküman ekle bölmesinde, beklendiği gibi eklendiğini doğrulamak için incelemeniz gereken dokümanı bulun.

Firestore Emulator&#39;daki belgeler

9. Web uygulamasından kullanıcı tarafından yüklenen dosyaları kaydetme

Bu bölümde, giriş yaptığınızda bir restoranla ilişkilendirilen resmi değiştirebilmeniz için işlevler eklersiniz. Görüntüyü Firebase Storage'a yükleyin ve restoranı temsil eden Cloud Firestore belgesindeki görüntü URL'sini güncelleyin.

Web uygulamasından kullanıcı tarafından yüklenen dosyaları kaydetmek için aşağıdaki adımları izleyin:

  1. src/components/Restaurant.jsx dosyasında, kullanıcı bir dosya yüklediğinde çalışan kodu bulun:
async function handleRestaurantImage(target) {
        const image = target.files ? target.files[0] : null;
        if (!image) {
                return;
        }

        const imageURL = await updateRestaurantImage(id, image);
        setRestaurant({ ...restaurant, photo: imageURL });
}

Herhangi bir değişiklik yapmanız gerekmez ancak updateRestaurantImage() işlevinin davranışını aşağıdaki adımlarda uygularsınız.

  1. src/lib/firebase/storage.js dosyasında updateRestaurantImage() ve uploadImage() işlevlerini aşağıdaki kodla değiştirin:
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);
}

updateRestaurantImageReference() işlevi sizin için zaten uygulanmıştır. Bu işlev, Cloud Firestore'daki mevcut bir restoran dokümanını güncellenmiş görüntü URL'siyle günceller.

Resim yükleme işlevini doğrulama

Resmin beklendiği gibi yüklendiğini doğrulamak için aşağıdaki adımları uygulayın:

  1. "Kullanıcıların her restoranı değiştirmesine izin ver" taahhüt mesajını içeren bir taahhüt oluşturun fotoğraf" kod deponuza gönderebilirsiniz.
  2. Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
  3. Web uygulamasında, giriş yaptığınızı doğrulayın ve bir restoran seçin.
  4. 7067eb41fea41ff0.png'yi tıklayın ve dosya sisteminizden bir resim yükleyin. Görüntünüz yerel ortamınızdan çıkar ve Cloud Storage'a yüklenir. Resim, yüklendikten hemen sonra görüntülenir.
  5. Firebase için Cloud Storage'a gidin.
  6. Restoranı temsil eden klasöre gidin. Yüklediğiniz resim klasörde bulunuyor.

6cf3f9e2303c931c.png

10. Restoran yorumlarını üretken yapay zeka ile özetleme

Bu bölümde yorum özeti özelliği ekleyeceksiniz. Böylece kullanıcılar her yorumu okumak zorunda kalmadan herkesin restoran hakkında düşündüklerini hızlı bir şekilde anlayabilecekler.

Gemini API anahtarını Cloud Secret Manager'da depolayın

  1. Gemini API'yi kullanmak için API anahtarına ihtiyacınız vardır. Google AI Studio'da anahtar oluşturun.
  2. Uygulama Barındırma, API anahtarları gibi hassas değerleri güvenli bir şekilde saklamanızı sağlamak için Cloud Secret Manager ile entegre olur:
    1. Bir terminalde, yeni gizli anahtar oluşturmak için komutu çalıştırın:
    firebase apphosting:secrets:set gemini-api-key
    
    1. Gizli anahtar değeri istendiğinde Google AI Studio'dan Gemini API anahtarınızı kopyalayıp yapıştırın.
    2. Yeni gizli anahtarın apphosting.yaml alanına eklenip eklenmemesi gerektiği sorulduğunda kabul etmek için Y yazın.

Gemini API anahtarınız artık Cloud Secret Manager'da güvenli bir şekilde saklanır ve Uygulama Barındırma arka ucunuz tarafından erişilebilir.

Yorum özeti bileşenini uygulama

  1. src/components/Reviews/ReviewSummary.jsx içinde GeminiSummary işlevini aşağıdaki kodla değiştirin:
    export async function GeminiSummary({ restaurantId }) {
        const { firebaseServerApp } = await getAuthenticatedAppForUser();
        const reviews = await getReviewsByRestaurantId(
            getFirestore(firebaseServerApp),
            restaurantId
        );
    
        const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
        const model = genAI.getGenerativeModel({ model: "gemini-pro"});
    
        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 {
            const result = await model.generateContent(prompt);
            const response = await result.response;
            const text = response.text();
    
            return (
                <div className="restaurant__review_summary">
                    <p>{text}</p>
                    <p> Summarized with Gemini</p>
                </div>
            );
        } catch (e) {
            console.error(e);
            return <p>Error contacting Gemini</p>;
        }
    }
    
  2. "Yorumları özetlemek için yapay zeka kullanın" taahhüt mesajıyla bir kayıt oluşturun kod deponuza gönderebilirsiniz.
  3. Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
  4. Bir restorana ait sayfayı açın. En üstte, sayfadaki tüm yorumların tek cümlelik bir özetini görürsünüz.
  5. Yeni yorum ekleyip sayfayı yenileyin. Özet değişikliğini göreceksiniz.

11. Sonuç

Tebrikler! Next.js uygulamasına özellik ve işlev eklemek için Firebase'i nasıl kullanacağınızı öğrendiniz. Özellikle şunları kullandınız:

Daha fazla bilgi