1. Başlamadan önce
Bu codelab'de, Firebase'i restoran yorumları web sitesi olan Friendly Eats adlı bir Next.js web uygulamasına nasıl entegre edeceğinizi öğreneceksiniz.
Tamamlanan web uygulaması, Firebase'in Next.js uygulamaları geliştirmenize nasıl yardımcı olabileceğini gösteren faydalı özellikler sunar. Bu özellikler şunlardır:
- Otomatik derleme ve dağıtım: Bu kod deneme çalışması, yapılandırılmış bir dallara her push yaptığınızda Next.js kodunuzu otomatik olarak derlemek ve dağıtmak için Firebase App Hosting'i kullanır.
- Oturum açma ve oturum kapatma: Tamamlanan web uygulaması, Google ile oturum açmanıza ve oturumu kapatmanıza olanak tanır. Kullanıcı girişi ve devamlılık tamamen Firebase Authentication üzerinden yönetilir.
- Resimler: 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. Bu herkese açık URL, daha sonra Cloud Firestore'daki ilgili restoran belgesinde depolanır.
- Yorumlar: Tamamlanmış web uygulaması, oturum açmış kullanıcıların restoranlar hakkında yıldız puanı ve metin tabanlı mesajdan oluşan yorumlar yayınlamasına olanak tanır. İnceleme bilgileri Cloud Firestore'da depolanır.
- Filtreler: Tamamlanmış web uygulaması, oturum açmış kullanıcıların restoran listesini kategoriye, konuma 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 hakkında bilgi
Neler öğreneceksiniz?
- Firebase'i Next.js uygulama yönlendiricisi ve sunucu tarafı oluşturma ile kullanma.
- Resimleri Firebase için Cloud Storage'da kalıcı hale getirme.
- Cloud Firestore veritabanında veri okuma ve yazma.
- Firebase JavaScript SDK'sı ile Google ile oturum açma özelliğini kullanma.
Gerekenler
- Git
- Node.js'in son kararlı sürümü
- Google Chrome gibi tercih ettiğiniz bir tarayıcı
- Kod düzenleyici ve terminal içeren bir geliştirme ortamı
- Firebase projenizi oluşturmak ve yönetmek 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'yi kullanır.
GitHub deposu oluşturma
Codelab kaynağını https://github.com/firebase/friendlyeats-web adresinde bulabilirsiniz. Depo, birden fazla platform için örnek projeler içerir. Ancak bu kod laboratuvarında yalnızca nextjs-start
dizini kullanılır. Aşağıdaki dizinleri göz önünde bulundurun:
* `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:
- Terminal kullanarak bilgisayarınızda yeni bir klasör oluşturun ve yeni dizine geçin:
mkdir codelab-friendlyeats-web cd codelab-friendlyeats-web
- Yalnızca
nextjs-start
klasörünü almak için giget npm paketini kullanın:npx giget@latest gh:firebase/friendlyeats-web/nextjs-start#master . --install
- git ile değişiklikleri yerel olarak izleme:
git init git commit -a -m "codelab starting point" git branch -M main
- Yeni bir GitHub deposu oluşturun: https://github.com/new. İstediğiniz adı verin.
- GitHub,
https://github.com/
veya/ .git git@github.com:
gibi görünen yeni bir depo URL'si sağlar. Bu URL'yi kopyalayın./ .git
- GitHub,
- Yerel değişiklikleri yeni GitHub deponuza aktarın.
yer tutucusunun yerine depo URL'nizi koyarak aşağıdaki komutu çalıştırın.git remote add origin <your-repository-url> git push -u origin main
- Artık GitHub deponuzda başlangıç kodunu görebilirsiniz.
Firebase CLI'yi yükleme veya güncelleme
Firebase CLI'nin yüklü olduğunu ve v13.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üyorsanız 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'yi yükleyemiyorsanız npm belgelerine göz atın veya başka bir yükleme seçeneği kullanın.
Firebase'e giriş yapma
- Firebase CLI'ye giriş yapmak için aşağıdaki komutu çalıştırın:
firebase login
- Firebase'in veri toplamasını isteyip istemediğinize bağlı olarak
Y
veyaN
değerini girin. - Tarayıcınızda Google Hesabınızı seçin ve ardından İzin ver'i tıklayın.
3. Firebase projenizi ayarlama
Bu bölümde, bir Firebase projesi oluşturacak ve bu projeyle bir Firebase web uygulaması ilişkilendireceksiniz. Ayrıca, örnek web uygulamasının kullandığı Firebase hizmetlerini de ayarlayacaksınız.
Firebase projesi oluşturma
- Firebase konsolunda Proje ekle'yi tıklayın.
- Proje adınızı girin metin kutusuna
FriendlyEats Codelab
(veya istediğiniz bir proje adı) girip Devam'ı tıklayın. - Firebase faturalandırma planını onaylayın modalinde planın Blaze olduğunu onaylayın ve ardından Planı onaylayın'ı tıklayın.
- Bu kod laboratuvarının çalışması için Google Analytics'e ihtiyacınız yoktur. Bu nedenle, Bu proje için Google Analytics'i etkinleştir seçeneğini devre dışı bırakın.
- Proje oluştur'u tıklayın.
- Projenizin temel hazırlığını yapılmasını bekleyin ve ardından Devam'ı tıklayın.
- Firebase projenizde Proje Ayarları'na gidin. Daha sonra ihtiyacınız olacağından proje kimliğinizi not edin. Bu benzersiz tanımlayıcı, projenizin kimliğini belirler (ör. Firebase CLI'de).
Firebase fiyatlandırma planınızı yükseltme
Firebase için Firebase Uygulama Barındırma ve Cloud Storage'ı kullanmak istiyorsanız Firebase projenizin kullandıkça öde (Blaze) fiyatlandırma planında olması gerekir. Yani projeniz bir Cloud Faturalandırma hesabına bağlı olmalıdır.
- Cloud Billing hesabı için kredi kartı gibi bir ödeme yöntemi gerekir.
- Firebase ve Google Cloud'da yeniyseniz 300 ABD doları kredi ve Ücretsiz Deneme Cloud Faturalandırma hesabı almaya uygun olup olmadığınızı kontrol edin.
- Bu kod laboratuvarını bir etkinlik kapsamında yapıyorsanız düzenleyen kişiye Cloud kredisi olup olmadığını sorun.
Projenizi Blaze planına yükseltmek için aşağıdaki adımları uygulayın:
- Firebase konsolunda planınızı yükseltmeyi seçin.
- Blaze planını seçin. Projenize bir Cloud Faturalandırma hesabı bağlamak için ekrandaki talimatları uygulayın.
Bu yükseltme kapsamında bir Cloud Faturalandırma hesabı oluşturmanız gerekiyorsa yükseltmeyi tamamlamak için Firebase Console'daki yükseltme akışına geri dönmeniz gerekebilir.
Firebase projenize web uygulaması ekleme
- Firebase projenizde Projeye genel bakış'a gidin ve ardından Web'i tıklayın.
Projenize kayıtlı uygulamalar varsa Web simgesini görmek için Uygulama ekle'yi tıklayın. - Uygulama takma adı metin kutusuna
My Next.js app
gibi akılda kalıcı bir uygulama takma adı girin. - Bu uygulama için Firebase Hosting'i de ayarlayın onay kutusunu işaretlemeden bırakın.
- Uygulama kaydet > İleri > İleri > Konsola devam et'i tıklayın.
Firebase konsolunda Firebase hizmetlerini ayarlama
Kimlik doğrulamayı ayarlama
- Firebase konsolunda Kimlik doğrulama'ya gidin.
- Başlayın'ı tıklayın.
- Ek sağlayıcılar sütununda Google > Etkinleştir'i tıklayın.
- Projenin herkese açık adı metin kutusuna
My Next.js app
gibi akılda kalıcı bir ad girin. - Proje için destek e-postası açılır listesinden e-posta adresinizi seçin.
- Kaydet'i tıklayın.
Cloud Firestore'u ayarlama
- Firebase konsolunun sol panelinde Derleme'yi genişletin ve ardından Firestore veritabanı'nı seçin.
- Create database'i (Veritabanı oluştur) tıklayın.
- Veritabanı Kimliği'ni
(default)
olarak bırakın. - Veritabanı için bir konum seçip Sonraki'yi tıklayın.
Gerçek bir uygulama için kullanıcılarınıza yakın bir konum seçmeniz gerekir. - Test modunda başlat'ı tıklayın. Güvenlik kurallarıyla ilgili sorumluluk reddi beyanını okuyun.
Bu kod laboratuvarının ilerleyen bölümlerinde, verilerinizin güvenliğini sağlamak için güvenlik kuralları ekleyeceksiniz. Veritabanınıza Güvenlik Kuralları eklemeden bir uygulamayı dağıtmayın veya herkese açık olarak göstermeyin. - Oluştur'u tıklayın.
Cloud Storage for Firebase'ı ayarlama
- Firebase konsolunun sol panelinde Derleme'yi genişletin ve ardından Depolama'yı seçin.
- Başlayın'ı tıklayın.
- Varsayılan Storage paketiniz için bir konum seçin.
US-WEST1
,US-CENTRAL1
veUS-EAST1
'deki paketler, Google Cloud Storage'ın "Daima Ücretsiz" katmanından yararlanabilir. Diğer tüm konumlardaki paketler için Google Cloud Storage fiyatlandırması ve kullanımı geçerlidir. - Test modunda başlat'ı tıklayın. Güvenlik kurallarıyla ilgili sorumluluk reddi beyanını okuyun.
Bu kod laboratuvarının ilerleyen bölümlerinde, verilerinizin güvenliğini sağlamak için güvenlik kuralları ekleyeceksiniz. Depolama alanı paketiniz için Güvenlik Kuralları eklemedenbir uygulamayı dağıtmayın veya herkese açık olarak göstermeyin. - Oluştur'u tıklayın.
4. Başlangıç kod tabanını inceleyin
Bu bölümde, uygulamanın başlangıç kod tabanının bu codelab'de işlev ekleyeceğiniz birkaç alanını inceleyeceksiniz.
Klasör ve dosya yapısı
Aşağıdaki tabloda, uygulamanın klasör ve dosya yapısına genel bir bakış sunulmaktadır:
Klasörler ve dosyalar | Açıklama |
| Filtreler, üstbilgiler, restoran ayrıntıları ve yorumlar için React bileşenleri |
| React veya Next.js'ye bağlı olmayan yardımcı işlevler |
| Firebase'e özgü kod ve Firebase yapılandırması |
| Web uygulamasındaki statik öğeler (ör. simgeler) |
| Next.js uygulama yönlendiricisiyle yönlendirme |
| API rota işleyicisi |
| npm ile proje bağımlılıkları |
| Next.js'ye özgü yapılandırma (sunucu işlemleri etkindir) |
| JavaScript dil hizmeti yapılandırması |
Sunucu ve istemci bileşenleri
Uygulama, uygulama yönlendiricisini kullanan bir Next.js web uygulamasıdır. Sunucu tarafı oluşturma, 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.
Ekstreleri içe aktarma
Aşağıdaki gibi içe aktarma beyanları görebilirsiniz:
import RatingPicker from "@/src/components/RatingPicker.jsx";
Uygulama, hantal göreli içe aktarma yollarını önlemek için @
simgesini kullanır ve bu, yol takma adları sayesinde mümkün olur.
Firebase'e özgü API'ler
Tüm Firebase API kodu src/lib/firebase
dizinine yerleştirilir. Ayrı 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ır. 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 bir App Hosting arka ucu oluşturacaksınız.
Bu bölümün sonunda, GitHub'daki deponuza bağlı bir App Hosting arka ucuna sahip olacaksınız. Bu arka uç, main
dalınıza yeni bir gönderim gönderdiğinizde uygulamanızı otomatik olarak yeniden derleyip yeni bir sürümünü kullanıma sunar.
Güvenlik kurallarını dağıtma
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.
- Terminalinizde, CLI'yi daha önce oluşturduğunuz Firebase projesini kullanacak şekilde yapılandırın:
firebase use --add
Takma ad istendiğindefriendlyeats-codelab
yazın. - Bu güvenlik kurallarını dağıtmak için terminalinizde şu komutu çalıştırın:
firebase deploy --only firestore:rules,storage
- Şu soruyu görürseniz:
"Cloud Storage for Firebase needs an IAM Role to use cross-service rules. Grant the new role?"
Evet'i seçmek içinEnter
'ye basın.
Firebase yapılandırmanızı web uygulaması kodunuza ekleme
- Firebase konsolunda Proje ayarlarınıza gidin.
- Yeni bir web uygulaması kaydetmek için SDK kurulumu ve yapılandırması bölmesinde "Uygulama ekle"yi ve kod parantezleri simgesini
tıklayın.
- Web uygulaması oluşturma akışının sonunda
firebaseConfig
değişkenini, özelliklerini ve değerlerini kopyalayın. - Kod düzenleyicinizde
apphosting.yaml
dosyasını açın ve ortam değişkeni değerlerini Firebase konsolundaki yapılandırma değerleriyle doldurun. - Dosyada, mevcut özellikleri kopyaladıklarınızla değiştirin.
- Dosyayı kaydedin.
Arka uç oluşturma
- Firebase konsolunda Uygulama Barındırma sayfasına gidin:
- Arka uç oluşturma akışını başlatmak için "Başlayın"ı tıklayın. Arka ucunuzu aşağıdaki gibi yapılandırın:
- Daha önce oluşturduğunuz GitHub deposunu bağlamak için ilk adımdaki talimatları uygulayın.
- Dağıtım ayarlarını yapın:
- Kök dizini
/
olarak kalsın - Canlı şubeyi
main
olarak ayarlayın - Otomatik kullanıma sunma işlemlerini etkinleştirme
- Kök dizini
- Arka uçunuzu
friendlyeats-codelab
olarak adlandırın. - "Firebase web uygulaması oluşturma veya ilişkilendirme" bölümünde, "Mevcut bir Firebase web uygulaması seçin" açılır menüsünden daha önce yapılandırdığınız web uygulamasını seçin.
- "Sonlandır ve dağıt"ı tıklayın. Bir süre sonra, yeni uygulama barındırma arka uç sunucunuzun durumunu görebileceğiniz yeni bir sayfaya yönlendirilirsiniz.
- Kullanıma sunma işleminiz tamamlandıktan sonra "Alanlar" bölümünde ücretsiz alanınızı tıklayın. DNS yayımı nedeniyle bu özelliğin çalışmaya başlaması birkaç dakika sürebilir.
İlk web uygulamasını dağıttınız. GitHub deponuzun main
dalına her yeni kaydetme işlemi aktardığınızda Firebase konsolunda yeni bir derleme ve dağıtım işleminin başladığını görürsünüz. Dağıtım tamamlandığında siteniz otomatik olarak güncellenir.
6. Web uygulamasına kimlik doğrulama ekleme
Bu bölümde, web uygulamasına giriş yapabilmeniz için kimlik doğrulaması eklersiniz.
Oturum açma ve oturumu kapatma işlevlerini uygulama
src/lib/firebase/auth.js
dosyasındaonAuthStateChanged
,signInWithGoogle
vesignOut
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 | Açıklama |
Google kimlik doğrulama sağlayıcı örneği oluşturur. | |
İletişime dayalı bir kimlik doğrulama akışı başlatır. | |
Kullanıcının oturumu kapatılır. |
src/components/Header.jsx
dosyasında kod zaten signInWithGoogle
ve signOut
işlevlerini çağırıyor.
- "Google Kimlik Doğrulaması Ekleniyor" mesajını içeren bir kaydetme işlemi oluşturun ve bu kaydetme işlemini GitHub deponuza gönderin. 1. Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
- 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ığı anlaşılamaz.
Kimlik doğrulama durumunu sunucuya gönderme
Kimlik doğrulama durumunu sunucuya iletmek için bir hizmet çalışanı kullanırı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);
}
Sunucudaki kimlik doğrulama durumunu okuma
İstemcinin kimlik doğrulama durumunu sunucuya yansıtmak için FirebaseServerApp'i kullanacağız.
src/lib/firebase/serverApp.js
dosyasını açıp 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 olma
Kimlik doğrulama değişikliklerine abone olmak için aşağıdaki adımları uygulayın:
src/components/Header.jsx
dosyasına gidin.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 React state kancası kullanır.
Değişiklikleri doğrulama
src/app/layout.js
dosyasındaki kök düzen, üstbilgiyi oluşturur ve varsa kullanıcıyı öğe olarak iletir.
<Header initialUser={currentUser?.toJSON()} />
Bu, <Header>
bileşeninin, sunucu çalışma zamanında (varsa) kullanıcı verilerini oluşturacağı anlamına gelir. İlk sayfa yükleme işleminden sonra sayfa yaşam döngüsü sırasında herhangi bir kimlik doğrulama güncellemesi olursa bunları onAuthStateChanged
işleyicisi yönetir.
Artık yeni bir derleme yayınlamanın ve oluşturduğunuzu doğrulamanın zamanı geldi.
- "Oturum açma durumunu göster" mesajını içeren bir gönderim oluşturun ve GitHub deponuza aktarın.
- Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
- Yeni kimlik doğrulama davranışını doğrulayın:
- Tarayıcınızda web uygulamasını yenileyin. Görünen adınız üstbilgide görünür.
- Oturumu kapatıp tekrar açın. Sayfa, sayfa yenilenmeden gerçek zamanlı olarak güncellenir. Bu adımı farklı kullanıcılarla tekrarlayabilirsiniz.
- İ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örüntüleme
Web uygulaması, restoranlar ve yorumlar için örnek veriler içerir.
Bir veya daha fazla restoran ekleme
Yerel Cloud Firestore veritabanınıza örnek restoran verileri eklemek için aşağıdaki adımları uygulayın:
- Web uygulamasında > Örnek restoran ekle'yi seçin.
- Firebase konsolundaki Firestore Veritabanı sayfasında restaurants'ı seçin. Restoran koleksiyonunda, her biri bir restoranı temsil eden üst düzey dokümanları görürsünüz.
- Bir restoran belgesinin özelliklerini keşfetmek için birkaç belgeyi tıklayın.
Restoran listesini görüntüleme
Cloud Firestore veritabanınızda artık Next.js web uygulamasının görüntüleyebileceği restoranlar var.
Veri getirme kodunu tanımlamak için aşağıdaki adımları uygulayın:
src/app/page.js
dosyasında<Home />
sunucu bileşenini bulun ve sunucu çalışma zamanında restoranların listesini alangetRestaurants
işlevinin çağrısını inceleyin.getRestaurants
işlevini aşağıdaki adımlarda uygularsınız.src/lib/firebase/firestore.js
dosyasındaapplyQueryFilters
vegetRestaurants
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(),
};
});
}
- "Firestore'dan restoran listesini oku" commit mesajını içeren bir commit oluşturun ve GitHub deponuza gönderin.
- Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
- Web uygulamasında sayfayı yenileyin. Restoran resimleri sayfada karolar olarak görünür.
Restoran listelemelerinin sunucu çalışma zamanında yüklendiğini doğrulama
Next.js çerçevesi kullanıldığında verilerin sunucu çalışma zamanında mı yoksa istemci tarafında çalışma zamanında mı yüklendiği açık olmayabilir.
Restoran listelemelerinin sunucu çalışma zamanında yüklendiğini doğrulamak için aşağıdaki adımları uygulayın:
- Web uygulamasında DevTools'u açın ve JavaScript'i devre dışı bırakın.
- Web uygulamasını yenileyin. Restoran girişleri yine yüklenir. Restoran bilgileri sunucu yanıtında döndürülür. JavaScript etkinleştirildiğinde restoran bilgileri, istemci tarafı JavaScript kodu aracılığıyla etkinleştirilir.
- Geliştirici Araçları'nda JavaScript'i yeniden etkinleştirin.
Cloud Firestore anlık görüntü dinleyicileriyle restoran güncellemelerini dinleme
Ö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 besleyecek şekilde yapılandırılabilir.
src/components/RestaurantListings.jsx
dosyasını, sunucu tarafından oluşturulan işaretlemeyi besleyecek şekilde yapılandırmak için aşağıdaki adımları uygulayın:
src/components/RestaurantListings.jsx
dosyasında, sizin için önceden yazılmış aşağıdaki kodu inceleyin:
useEffect(() => {
const unsubscribe = getRestaurantsSnapshot(data => {
setRestaurants(data);
}, filters);
return () => {
unsubscribe();
};
}, [filters]);
Bu kod, önceki bir adımda uyguladığınız getRestaurants()
işlevine benzer bir getRestaurantsSnapshot()
işlevi çağırır. Ancak bu anlık görüntü işlevi, restoran 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.
src/lib/firebase/firestore.js
dosyasındagetRestaurantsSnapshot()
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 anında yansıtılıyor.
- "Gerçek zamanlı restoran güncellemelerini dinleyin" mesajını içeren bir kaydetme işlemi oluşturun ve bu kaydetme işlemini GitHub deponuza gönderin.
- Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
- Web uygulamasında > Örnek restoran ekle'yi seçin. Anlık görüntü işleviniz doğru şekilde uygulandıysa restoranlar sayfa yenilenmeden anlık olarak gösterilir.
8. Web uygulamasından kullanıcı tarafından gönderilen yorumları kaydetme
src/lib/firebase/firestore.js
dosyasındaupdateWithRating()
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 dokümanı ekler. Kod, restoranı temsil eden mevcut Firestore belgesini de puan sayısı ve ortalama hesaplanan puanla ilgili güncellenmiş rakamlarla günceller.
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 işlemi uygulama
Next.js sunucu işlemi, form verilerine erişmek için uygun bir API sağlar. Örneğin, form gönderme yükünden metin değerini almak için data.get("text")
kullanılabilir.
İnceleme formu gönderimini işlemek için Next.js sunucu işlemi kullanmak üzere aşağıdaki adımları uygulayın:
src/components/ReviewDialog.jsx
dosyasında,<form>
öğesindeaction
özelliğini bulun.
<form action={handleReviewFormSubmission}>
action
özellik değeri, bir sonraki adımda uygulayacağınız bir işlevi ifade eder.
src/app/actions.js
dosyasındahandleReviewFormSubmission()
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"),
});
}
Restoran yorumları ekleme
Yorum gönderimleri için destek uyguladığınızdan artık yorumlarınızın Cloud Firestore'a doğru şekilde eklendiğini doğrulayabilirsiniz.
Yorum eklemek ve bu yorumun Cloud Firestore'a eklendiğini doğrulamak için aşağıdaki adımları uygulayın:
- "Kullanıcıların restoran yorumları göndermesine izin ver" mesajını içeren bir commit oluşturun ve bunu GitHub deponuza gönderin.
- Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
- Web uygulamasını yenileyin ve ana sayfadan bir restoran seçin.
- Restoranın sayfasında simgesini tıklayın.
- Bir yıldız puanı seçin.
- Yorum yazın.
- Gönder'i tıklayın. Yorumunuz, yorum listesinin en üstünde görünür.
- Cloud Firestore'da, Doküman ekle bölmesinde incelediğiniz restoranın dokümanlarını arayın ve seçin.
- Veri toplamaya başla bölmesinde değerlendirmeler'i seçin.
- Doküman ekle bölmesinde, incelemeniz için eklediğiniz dokümanı bulun ve beklenen şekilde eklendiğini doğrulayın.
9. Kullanıcı tarafından yüklenen dosyaları web uygulamasından kaydetme
Bu bölümde, giriş yaptığınızda bir restoranla ilişkili resmi değiştirebilmeniz için işlev eklersiniz. Resmi Firebase Storage'a yükler ve restoranı temsil eden Cloud Firestore dokümanında resim URL'sini güncelleyebilirsiniz.
Kullanıcı tarafından yüklenen dosyaları web uygulamasından kaydetmek için aşağıdaki adımları uygulayın:
src/components/Restaurant.jsx
dosyasında, kullanıcı bir dosya yüklediğinde çalıştırılan kodu inceleyin:
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 });
}
Değişiklik yapmanız gerekmez ancak aşağıdaki adımlarda updateRestaurantImage()
işlevinin davranışını uygularsınız.
src/lib/firebase/storage.js
dosyasındaupdateRestaurantImage()
veuploadImage()
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ış. Bu işlev, Cloud Firestore'daki mevcut bir restoran dokümanındaki resim URL'sini güncellenmiş bir resim 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:
- "Kullanıcıların her restoranın fotoğrafını değiştirmesine izin ver" commit mesajını içeren bir commit oluşturun ve GitHub deponuza aktarın.
- Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
- Web uygulamasında giriş yaptığınızdan emin olun ve bir restoran seçin.
- simgesini tıklayın ve dosya sisteminizden bir resim yükleyin. Görüntünüz yerel ortamınızdan ayrılır ve Cloud Storage'a yüklenir. Resim, yüklendikten hemen sonra gösterilir.
- Firebase için Cloud Storage'a gidin.
- Restoranı temsil eden klasöre gidin. Yüklediğiniz resim klasörde mevcut.
10. Üretken yapay zeka ile restoran yorumlarını özetleme
Bu bölümde, kullanıcıların her yorumu okumak zorunda kalmadan bir restoran hakkındaki genel fikri hızlıca anlayabilmesi için bir yorum özeti özelliği ekleyeceksiniz.
Cloud Secret Manager'da Gemini API anahtarı depolama
- Gemini API'yi kullanmak için bir API anahtarına ihtiyacınız vardır. Google AI Studio'da bir anahtar oluşturun.
- Uygulama Barındırma, API anahtarları gibi hassas değerleri güvenli bir şekilde depolamanıza olanak tanımak için Cloud Secret Manager ile entegre çalışır:
- Terminalde yeni bir gizli anahtar oluşturmak için şu komutu çalıştırın:
firebase apphosting:secrets:set gemini-api-key
- Gizli değer istendiğinde Google AI Studio'dan Gemini API anahtarınızı kopyalayıp yapıştırın.
- Yeni gizli anahtarın
apphosting.yaml
'e eklenip eklenmeyeceği sorulduğunda kabul etmek içinY
yazın.
Gemini API anahtarınız artık Cloud Secret Manager'da güvenli bir şekilde depolanır ve uygulama barındırma arka ucunuz tarafından erişilebilir.
Yorum özeti bileşenini uygulama
src/components/Reviews/ReviewSummary.jsx
dosyasındaGeminiSummary
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>; } }
- "Yorumları özetlemek için yapay zekadan yararlanın" mesajını içeren bir değişiklik kaydı oluşturun ve bu değişikliği GitHub deponuza gönderin.
- Firebase konsolunda Uygulama Barındırma sayfasını açın ve yeni kullanıma sunma işleminizin tamamlanmasını bekleyin.
- Bir restoranın sayfasını açın. Sayfanın üst kısmında, sayfadaki tüm yorumların tek cümlelik bir özetini görürsünüz.
- Yeni bir yorum ekleyin ve sayfayı yenileyin. Özet değişecektir.
11. Sonuç
Tebrikler! Next.js uygulamasına özellik ve işlev eklemek için Firebase'i nasıl kullanacağınızı öğrendiniz. Özellikle aşağıdakileri kullandınız:
- Yapılandırılmış bir dala her aktarma işleminde Next.js kodunuzu otomatik olarak derleyip dağıtmak için Firebase App Hosting'i kullanın.
- Oturum açma ve oturum kapatma işlevini etkinleştirmek için Firebase Authentication.
- Restoran verileri ve restoran yorumu verileri için Cloud Firestore.
- Restoran resimleri için Cloud Storage for Firebase.