Bir uygulama geliştiriyorsunuz. Kullanıcıların oturum açması gerekiyor. Verilerin gerçek zamanlı olarak senkronize edilmesi gerekiyor. Dosyaların depolanması gerekiyor. Sunucular kurabilir, veritabanlarını yapılandırabilir ve altyapıyı haftalarca yönetebilirsiniz. Veya Firebase kullanabilirsiniz.
Firebase, The New York Times, Duolingo ve Alibaba dahil olmak üzere 1,5 milyondan fazla uygulamayı desteklemektedir. Geliştiriciler onu tercih ediyor çünkü arka uç karmaşasını ortadan kaldırıyor. Siz özelliklere odaklanırsınız, sunucu bakımına değil. Ancak Firebase API'sinin kendine özgü bazı yönleri var. Kimlik doğrulama akışları yeni başlayanların kafasını karıştırır. Veritabanı kuralları deneyimli geliştiricileri bile zorlar. Cloud Functions, tetikleyicileri anlayana kadar büyülü görünür.
Firebase'i milyonlarca kullanıcıya hizmet veren üretim uygulamalarına entegre ettim. Mümkün olan her hatayı yaptım: servis hesabı anahtarlarını ifşa ettim, verimsiz sorgular yazdım, bozuk fonksiyonlar dağıttım. Bu kılavuz bu dersleri damıtıyor.
Kimlik doğrulama, veritabanı işlemleri, Cloud Functions ve depolama konularını öğreneceksiniz. Sadece teori değil, çalışan kodlar göreceksiniz. Üretimdeki sorunlara yol açan tuzaklardan kaçınacaksınız.
Firebase API Nedir ve Neden Önemlidir?
Firebase tek bir API değildir. Birleşik SDK'lar ve REST uç noktaları aracılığıyla erişilen bir arka uç hizmetleri paketidir.
Temel Firebase Hizmetleri
| Hizmet | Amaç | API Türü |
|---|---|---|
| Kimlik Doğrulama | Kullanıcı girişi ve kimlik | SDK + REST |
| Firestore Veritabanı | NoSQL doküman veritabanı | SDK + REST |
| Gerçek Zamanlı Veritabanı | JSON gerçek zamanlı senkronizasyon | SDK + REST |
| Cloud Storage | Dosya depolama ve CDN | SDK + REST |
| Cloud Functions | Sunucusuz hesaplama | Dağıtım CLI'ı |
| Hosting | Statik web barındırma | Dağıtım CLI'ı |
| Cloud Messaging | Anlık bildirimler | HTTP v1 API |
Firebase Ne Zaman Mantıklıdır?
Firebase belirli sorunları iyi çözer:
Firebase'i şu durumlarda kullanın:
- Gerçek zamanlı senkronizasyona ihtiyacınız var (sohbet, işbirliği, canlı güncellemeler)
- Sunucusuz mimari istiyorsunuz (altyapı yönetimi yok)
- Mobil veya web uygulamaları geliştiriyorsunuz (SDK'lar platform farklılıklarını halleder)
- Çevrimdışı desteğe ihtiyacınız var (SDK'lar verileri otomatik olarak önbelleğe alır)
- Yerleşik kimlik doğrulaması istiyorsunuz (Google, Apple, e-posta, telefon girişi)
Firebase'i şu durumlarda atlayın:
- Karmaşık ilişkisel sorgulara ihtiyacınız var (bunun yerine PostgreSQL kullanın)
- Sıkı veri yerleşimi gereksinimleriniz var (Firebase bölgeleri sınırlıdır)
- Tam SQL yeteneklerine ihtiyacınız var (Firestore sorgu sınırlamaları mevcut)
- Ölçekteki maliyet, geliştirme hızından daha önemlidir (kendi barındırma daha ucuzdur)
Firebase API Mimarisi
Firebase hibrit bir yaklaşım kullanır:
┌─────────────────────────────────────────────────────────┐
│ Uygulamanız │
├─────────────────────────────────────────────────────────┤
│ Firebase SDK (İstemci) │
│ - Kimlik doğrulama belirteçlerini otomatik olarak işler │
│ - Çevrimdışı önbelleği yönetir │
│ - Gerçek zamanlı dinleyiciler │
└─────────────────────────────────────────────────────────┘
│
│ HTTPS + WebSocket
▼
┌─────────────────────────────────────────────────────────┐
│ Firebase Arka Ucu │
├──────────────┬──────────────┬──────────────┬────────────┤
│ Kimlik │ Firestore │ Depolama │ Fonksiyonlar │
│ Hizmeti │ Veritabanı │ Hizmeti │ Çalışma Ortamı │
└──────────────┴──────────────┴──────────────┴────────────┘
İstemci SDK'ları HTTP katmanını soyutlar. Kaputun altında, her işlem JWT kimlik doğrulamasıyla REST API çağrılarına dönüşür.
Firebase Kimlik Doğrulama: Tam Kurulum
Kimlik doğrulama, ilk Firebase entegrasyonunuzdur. Bunu yanlış yaparsanız, diğer her şey başarısız olur.
Adım 1: Firebase Projesi Oluşturun
- Firebase Konsolu'na gidin

"Proje ekle"ye tıklayın ve proje adını girin (boşluksuz)

Google Analytics'i etkinleştirin (isteğe bağlı ama önerilir)

"Proje oluştur"a tıklayın

Sağlama için 30 saniye bekleyin. Proje panosunu göreceksiniz.
Adım 2: Uygulamanızı Kaydedin
Web Uygulamaları için:
// Firebase Konsolu > Proje Ayarları > Genel kısmında
// "Uygulama ekle" > Web simgesine tıklayın
// Web uygulamasını kaydedin
const firebaseConfig = {
apiKey: "AIzaSyDxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "uygulamaniz.firebaseapp.com",
projectId: "uygulamaniz",
storageBucket: "uygulamaniz.appspot.com",
messagingSenderId: "123456789012",
appId: "1:123456789012:web:abc123def456"
};
// Firebase'i başlatın
import { initializeApp } from 'firebase/app';
const app = initializeApp(firebaseConfig);
iOS Uygulamaları için:
GoogleService-Info.plist dosyasını indirin ve Xcode projenize ekleyin. "Target Membership"in uygulamanızı içerdiğinden emin olun.
Android Uygulamaları için:
google-services.json dosyasını indirin ve app/ dizinine yerleştirin. build.gradle dosyasına ekleyin:
// Proje düzeyinde build.gradle
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.4.0'
}
}
// Uygulama düzeyinde build.gradle
plugins {
id 'com.google.gms.google-services'
}
Adım 3: Kimlik Doğrulama Yöntemlerini Etkinleştirin
Firebase Konsolu > Kimlik Doğrulama > Oturum açma yöntemi bölümünde:
- E-posta/Şifre: Geleneksel kayıt için etkinleştirin
- Google: SHA-1 sertifika parmak izinizi (Android) veya paket kimliğinizi (iOS) ekleyin
- Apple: Herhangi bir sosyal girişi etkinleştirirseniz iOS uygulamaları için gereklidir
- Telefon: SMS kimlik doğrulaması için etkinleştirin (faturalandırma gerektirir)
Adım 4: Kimlik Doğrulama Akışını Uygulayın
E-posta/Şifre ile Kayıt:
import {
createUserWithEmailAndPassword,
getAuth,
updateProfile
} from 'firebase/auth';
const auth = getAuth(app);
async function signUp(email, password, displayName) {
try {
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
);
// Görünen adı ayarlayın
await updateProfile(userCredential.user, {
displayName: displayName
});
console.log('Kullanıcı oluşturuldu:', userCredential.user.uid);
return userCredential.user;
} catch (error) {
// Belirli hata kodlarını ele alın
switch (error.code) {
case 'auth/email-already-in-use':
throw new Error('Bu e-posta zaten kayıtlı');
case 'auth/weak-password':
throw new Error('Şifre en az 6 karakter olmalı');
case 'auth/invalid-email':
throw new Error('Geçersiz e-posta adresi');
default:
throw new Error('Kayıt başarısız: ' + error.message);
}
}
}
E-posta/Şifre ile Giriş:
import {
signInWithEmailAndPassword,
signOut
} from 'firebase/auth';
async function signIn(email, password) {
try {
const userCredential = await signInWithEmailAndPassword(
auth,
email,
password
);
const user = userCredential.user;
// API çağrıları için ID belirteci alın
const idToken = await user.getIdToken();
console.log('Kimlik doğrulama belirteci:', idToken);
return user;
} catch (error) {
switch (error.code) {
case 'auth/user-not-found':
throw new Error('Bu e-posta ile hesap bulunamadı');
case 'auth/wrong-password':
throw new Error('Yanlış şifre');
case 'auth/too-many-requests':
throw new Error('Çok fazla deneme. Daha sonra tekrar deneyin');
default:
throw new Error('Giriş başarısız oldu');
}
}
}
async function logOut() {
await signOut(auth);
console.log('Kullanıcı çıkış yaptı');
}
Google ile Giriş (Web):
import {
GoogleAuthProvider,
signInWithPopup
} from 'firebase/auth';
async function signInWithGoogle() {
const provider = new GoogleAuthProvider();
// Ek kapsamlar isteyin
provider.addScope('email');
provider.addScope('profile');
try {
const result = await signInWithPopup(auth, provider);
const user = result.user;
// Google OAuth belirtecine erişin
const credential = GoogleAuthProvider.credentialFromResult(result);
const googleAccessToken = credential.accessToken;
return user;
} catch (error) {
if (error.code === 'auth/popup-closed-by-user') {
throw new Error('Giriş iptal edildi');
}
throw new Error('Google ile giriş başarısız oldu');
}
}
Adım 5: Kimlik Doğrulama Durumu ile Rotaları Koruyun
import { onAuthStateChanged } from 'firebase/auth';
// Kimlik doğrulama durumu değişikliklerini dinleyin
onAuthStateChanged(auth, (user) => {
if (user) {
// Kullanıcı oturum açmış
console.log('Kullanıcı:', user.email);
// Panoya yönlendirin
window.location.href = '/dashboard';
} else {
// Kullanıcı oturum açmamış
console.log('Kullanıcı yok');
// Giriş sayfasına yönlendirin
window.location.href = '/login';
}
});
Yaygın Kimlik Doğrulama Hataları
Hata 1: Belirteç yenilemesini ele almamak
Firebase SDK belirteçleri otomatik olarak yeniler. Ancak belirteçleri sunucu tarafında önbelleğe alırsanız, 1 saat sonra süreleri dolar. Her istekte belirteçleri doğrulayın veya yenileme mantığını uygulayın.
Hata 2: İstemci kodunda yönetici kimlik bilgilerini ifşa etmek
İstemci uygulamalarında servis hesabı anahtarlarını asla kullanmayın. Servis hesapları güvenlik kurallarını atlar. Yalnızca güvenilir sunucu ortamlarında kullanın.
Hata 3: E-posta doğrulamasını atlamak
import { sendEmailVerification } from 'firebase/auth';
async function sendVerificationEmail(user) {
await sendEmailVerification(user);
console.log('Doğrulama e-postası gönderildi');
}
// Doğrulama durumunu kontrol edin
if (!auth.currentUser.emailVerified) {
console.log('E-posta doğrulanmadı');
// Erişimi kısıtla
}
Firestore Veritabanı: İşlemler ve Sorgular
Firestore, Firebase'in NoSQL veritabanıdır. Dokümanlar koleksiyonlar halinde düzenlenir. Sorgular otomatik olarak ölçeklenir.
Veri Yapısı
projeniz (kök)
└── kullanıcılar (koleksiyon)
├── userId123 (doküman)
│ ├── ad: "John"
│ ├── e-posta: "john@example.com"
│ └── gönderiler (alt koleksiyon)
│ ├── postId1 (doküman)
│ └── postId2 (doküman)
└── userId456 (doküman)
Firestore'u Başlatın
import { getFirestore } from 'firebase/firestore';
const db = getFirestore(app);
Doküman Oluşturun
import {
collection,
addDoc,
setDoc,
doc
} from 'firebase/firestore';
// Seçenek 1: Otomatik oluşturulan kimlik
async function createUser(userData) {
const docRef = await addDoc(collection(db, 'users'), userData);
console.log('Doküman ID ile yazıldı:', docRef.id);
return docRef.id;
}
// Seçenek 2: Özel kimlik
async function createUserWithId(userId, userData) {
await setDoc(doc(db, 'users', userId), userData);
console.log('Doküman özel ID ile yazıldı:', userId);
}
// Kullanım
const userId = await createUser({
name: 'Alice',
email: 'alice@example.com',
createdAt: new Date(),
role: 'user'
});
Dokümanları Okuyun
import {
getDoc,
getDocs,
query,
where,
orderBy,
limit
} from 'firebase/firestore';
// Tek bir dokümanı alın
async function getUser(userId) {
const docRef = doc(db, 'users', userId);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
return docSnap.data();
} else {
throw new Error('Kullanıcı bulunamadı');
}
}
// Filtrelerle sorgulayın
async function getUsersByRole(role) {
const q = query(
collection(db, 'users'),
where('role', '==', role),
orderBy('createdAt', 'desc'),
limit(10)
);
const querySnapshot = await getDocs(q);
const users = [];
querySnapshot.forEach((doc) => {
users.push({ id: doc.id, ...doc.data() });
});
return users;
}
// Kullanım
const adminUsers = await getUsersByRole('admin');
console.log('Yönetici kullanıcılar:', adminUsers);
Dokümanları Güncelleyin
import {
updateDoc,
increment,
arrayUnion,
arrayRemove
} from 'firebase/firestore';
async function updateUser(userId, updates) {
const userRef = doc(db, 'users', userId);
await updateDoc(userRef, updates);
}
// Atomik işlemler
await updateUser('userId123', {
loginCount: increment(1),
tags: arrayUnion('premium', 'beta-tester'),
lastLogin: new Date()
});
// Diziden kaldır
await updateUser('userId123', {
tags: arrayRemove('beta-tester')
});
Dokümanları Silin
import { deleteDoc } from 'firebase/firestore';
async function deleteUser(userId) {
await deleteDoc(doc(db, 'users', userId));
console.log('Kullanıcı silindi');
}
Gerçek Zamanlı Dinleyiciler
import { onSnapshot } from 'firebase/firestore';
// Tek bir dokümanı dinle
const unsubscribe = onSnapshot(
doc(db, 'users', userId),
(doc) => {
console.log('Kullanıcı güncellendi:', doc.data());
},
(error) => {
console.error('Dinleme hatası:', error);
}
);
// Sorgu sonuçlarını dinle
const q = query(collection(db, 'posts'), where('published', '==', true));
const unsubscribeQuery = onSnapshot(q, (snapshot) => {
const posts = snapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
console.log('Yayınlanmış gönderiler:', posts);
});
// Dinlemeyi durdur
unsubscribe();
unsubscribeQuery();
Firestore Güvenlik Kuralları
Uygun kurallar olmadan, herkes verilerinizi okuyabilir. Firebase Konsolu > Firestore > Kurallar bölümünde kuralları ayarlayın:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Yardımcı fonksiyon
function isAuthenticated() {
return request.auth != null;
}
function isOwner(userId) {
return request.auth.uid == userId;
}
// Kullanıcılar koleksiyonu
match /users/{userId} {
allow read: if isAuthenticated();
allow create: if isAuthenticated() && isOwner(userId);
allow update, delete: if isOwner(userId);
}
// Gönderiler koleksiyonu
match /posts/{postId} {
allow read: if true; // Genel okuma
allow create: if isAuthenticated();
allow update, delete: if resource.data.authorId == request.auth.uid;
}
// Özel alt koleksiyon
match /users/{userId}/private/{document} {
allow read, write: if isOwner(userId);
}
}
}
Sorgu Sınırlamaları
Firestore'un kısıtlamaları vardır:
- OR sorguları yok (dizi veya çoklu sorgularla
inkullanın) - Joker karakter aramaları yok (tam metin için Algolia veya Meilisearch kullanın)
- Bileşik sorguların indekslere ihtiyacı var (Firestore tek alanlı indeksleri otomatik oluşturur)
insorgularında 30 ayrıklık sınırı
OR sorguları için geçici çözüm:
// Bunun yerine: where('status', '==', 'active') OR where('status', '==', 'pending')
const activeQuery = query(
collection(db, 'tasks'),
where('status', '==', 'active')
);
const pendingQuery = query(
collection(db, 'tasks'),
where('status', '==', 'pending')
);
const [activeSnap, pendingSnap] = await Promise.all([
getDocs(activeQuery),
getDocs(pendingQuery)
]);
// Sonuçları istemcide birleştirin
Cloud Functions: Sunucusuz Arka Uç Mantığı
Cloud Functions, sunucuları yönetmeden arka uç kodu çalıştırır. Veritabanı değişiklikleri, HTTP istekleri veya zamanlanmış olaylar üzerinde tetiklenir.
Kurulum
# Firebase CLI'yi yükleyin
npm install -g firebase-tools
# Giriş yapın
firebase login
# Projenizde fonksiyonları başlatın
firebase init functions
# Seçin: JavaScript, ESLint evet, Express.js hayır
HTTP Fonksiyonları (API Uç Noktaları)
// functions/index.js
const { onRequest } = require('firebase-functions/v2/https');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
// Genel uç nokta
exports.getPublicData = onRequest(async (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
try {
const snapshot = await db.collection('public').get();
const data = snapshot.docs.map(doc => doc.data());
res.json({ success: true, data });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Korumalı uç nokta (kimlik doğrulama belirtecini doğrulayın)
exports.getUserProfile = onRequest(async (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
// Authorization başlığından belirteci alın
const authHeader = req.headers.authorization || '';
const token = authHeader.split('Bearer ')[1];
if (!token) {
return res.status(401).json({ error: 'Yetkisiz' });
}
try {
// Belirteci doğrulayın
const decodedToken = await admin.auth().verifyIdToken(token);
const userId = decodedToken.uid;
// Kullanıcı verilerini alın
const userDoc = await db.collection('users').doc(userId).get();
if (!userDoc.exists) {
return res.status(404).json({ error: 'Kullanıcı bulunamadı' });
}
res.json({
success: true,
data: { id: userId, ...userDoc.data() }
});
} catch (error) {
res.status(401).json({ error: 'Geçersiz belirteç' });
}
});
Dağıt:
firebase deploy --only functions:getUserProfile
İstemciden çağır:
async function getUserProfile(token) {
const response = await fetch(
'https://us-central1-uygulamaniz.cloudfunctions.net/getUserProfile',
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
const data = await response.json();
return data;
}
Veritabanı Tetikleyicileri
const { onDocumentWritten } = require('firebase-functions/v2/firestore');
// Kullanıcı dokümanı değiştiğinde tetikle
exports.onUserUpdate = onDocumentWritten(
'users/{userId}',
async (event) => {
const userId = event.params.userId;
const before = event.data?.before?.data();
const after = event.data?.after?.data();
// E-posta değişti mi kontrol et
if (before?.email !== after?.email) {
console.log(`Kullanıcı ${userId} e-postası değişti: ${before?.email} → ${after?.email}`);
// Bildirim e-postası gönder
await admin.auth().getUser(userId);
// E-posta mantığınızı buraya ekleyin
}
}
);
// Yeni gönderi oluşturulduğunda tetikle
exports.onNewPost = onDocumentWritten(
'posts/{postId}',
async (event) => {
const post = event.data?.after?.data();
if (!post) return; // Doküman silindi
// Bu yeni bir doküman mı kontrol et
if (!event.data?.before?.exists) {
console.log('Yeni gönderi oluşturuldu:', post.title);
// Takipçilere bildir
const followersSnap = await admin.firestore()
.collection('users')
.where('following', 'array-contains', post.authorId)
.get();
const notifications = followersSnap.docs.map(doc => ({
userId: doc.id,
postId: event.params.postId,
type: 'new_post',
createdAt: admin.firestore.FieldValue.serverTimestamp()
}));
const batch = admin.firestore().batch();
notifications.forEach(notif => {
const ref = admin.firestore().collection('notifications').doc();
batch.set(ref, notif);
});
await batch.commit();
}
}
);
Zamanlanmış Fonksiyonlar (Cron İşleri)
const { onSchedule } = require('firebase-functions/v2/scheduler');
// Her gün gece yarısı UTC'de çalıştır
exports.dailyCleanup = onSchedule('every 24 hours', async (event) => {
console.log('Günlük temizlik çalışıyor');
// Eski bildirimleri sil (30+ gün)
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
const oldNotifs = await admin.firestore()
.collection('notifications')
.where('createdAt', '<', thirtyDaysAgo)
.get();
const batch = admin.firestore().batch();
oldNotifs.forEach(doc => batch.delete(doc.ref));
await batch.commit();
console.log(`${oldNotifs.size} eski bildirim silindi`);
});
Ortam Yapılandırması
# Ortam değişkenlerini ayarlayın
firebase functions:config:set \
stripe.secret="sk_test_xxx" \
email.api_key="key_xxx"
# Fonksiyonlarda erişim
const config = require('firebase-functions/config');
const stripe = require('stripe')(config.stripe.secret);
Cloud Storage: Dosya Yükleme ve Yönetimi
Kullanıcı yüklemelerini, resimleri ve dosyaları otomatik CDN dağıtımıyla depolayın.
Depolama Kurallarını Ayarlayın
// Firebase Konsolu > Depolama > Kurallar
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// Kullanıcı yüklemeleri klasörü
match /users/{userId}/{allPaths=**} {
allow read: if true; // Genel okuma
allow write: if request.auth.uid == userId;
allow delete: if request.auth.uid == userId;
}
// Genel varlıklar
match /public/{allPaths=**} {
allow read: if true;
allow write: if false; // Sadece Firebase Konsolu üzerinden yönetici
}
}
}
Dosya Yükle (İstemci)
import {
getStorage,
ref,
uploadBytesResumable,
getDownloadURL
} from 'firebase/storage';
const storage = getStorage(app);
async function uploadProfileImage(userId, file) {
// Depolama referansı oluşturun
const storageRef = ref(storage, `users/${userId}/profile/${file.name}`);
// Dosya yükleyin
const uploadTask = uploadBytesResumable(storageRef, file);
return new Promise((resolve, reject) => {
uploadTask.on(
'state_changed',
(snapshot) => {
// İlerlemeyi takip et
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log(`Yükleme: ${progress.toFixed(0)}%`);
},
(error) => {
// Hataları ele al
switch (error.code) {
case 'storage/unauthorized':
reject(new Error('Yetkiniz yok'));
break;
case 'storage/canceled':
reject(new Error('Yükleme iptal edildi'));
break;
default:
reject(new Error('Yükleme başarısız oldu'));
}
},
async () => {
// Yükleme tamamlandı
const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
console.log('Dosya şu adreste mevcut:', downloadURL);
resolve(downloadURL);
}
);
});
}
// Kullanım
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
if (file) {
const imageUrl = await uploadProfileImage(auth.currentUser.uid, file);
// URL'yi Firestore'a kaydet
await updateDoc(doc(db, 'users', auth.currentUser.uid), {
profileImage: imageUrl
});
}
Dosya İndir
import { getDownloadURL } from 'firebase/storage';
async function getProfileImage(userId) {
const imageRef = ref(storage, `users/${userId}/profile/avatar.png`);
try {
const url = await getDownloadURL(imageRef);
return url;
} catch (error) {
if (error.code === 'storage/object-not-found') {
return null; // Profil resmi yok
}
throw error;
}
}
Dosya Sil
import { deleteObject } from 'firebase/storage';
async function deleteProfileImage(userId) {
const imageRef = ref(storage, `users/${userId}/profile/avatar.png`);
await deleteObject(imageRef);
console.log('Profil resmi silindi');
}
Firebase API'lerini Apidog ile Test Etme
Firebase, tüm hizmetler için REST API'leri sağlar. Bunları doğrudan test etmek, sorunları gidermeye ve temel istekleri anlamaya yardımcı olur.
Firebase REST API'sini İçe Aktar
- Apidog'u açın
- Yeni proje oluşturun: "Firebase API"
- Firebase belgelerinden OpenAPI spesifikasyonunu içe aktarın
- Veya uç noktaları manuel olarak ekleyin:
Firestore REST Uç Noktası:
POST https://firestore.googleapis.com/v1/projects/{projectId}/databases/(default)/documents
Authorization: Bearer {oauth2_token}
Content-Type: application/json
{
"fields": {
"name": { "stringValue": "John" },
"email": { "stringValue": "john@example.com" },
"age": { "integerValue": 30 }
}
}
Kimlik Doğrulama Uç Noktası:
POST https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={api_key}
Content-Type: application/json
{
"email": "user@example.com",
"password": "secret123",
"returnSecureToken": true
}
Kimlik Doğrulama Akışını Test Et
- İstek oluştur: "Giriş Yap"
- Yöntemi ayarla: POST
- Gövdeye e-posta/şifre ekle
- Yanıt belirtecini ortam değişkeni olarak kaydet
- Sonraki isteklerde
{{token}}kullanın
Güvenlik Kurallarında Hata Ayıkla
Yerel testler için Firebase Emulator Suite'i kullanın:
# Emülatörü başlat
firebase emulators:start
# Yerel Firestore'a karşı test et
# http://localhost:8080
Üretim En İyi Uygulamaları
1. Uygun Hata İşleme Uygulayın
// Geçici hatalar için yeniden deneme mantığı
async function firestoreWithRetry(operation, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
if (
error.code === 'unavailable' ||
error.code === 'deadline-exceeded'
) {
const delay = Math.pow(2, i) * 1000; // Üstel geri çekilme
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
2. Sorgu Performansını Optimize Edin
Çok alanlı sorgular için bileşik indeksler ekleyin:
// Bu sorgu bileşik bir indekse ihtiyaç duyar
const q = query(
collection(db, 'posts'),
where('category', '==', 'tech'),
where('views', '>', 1000),
orderBy('views', 'desc')
);
Firestore, bu sorguyu çalıştırdığınızda doğrudan bir bağlantıyla gerekli indeksi oluşturmanızı ister.
3. Toplu İşlemler
import { writeBatch } from 'firebase/firestore';
async function bulkUpdate(userIds, updates) {
const batch = writeBatch(db);
userIds.forEach(id => {
const ref = doc(db, 'users', id);
batch.update(ref, updates);
});
await batch.commit();
console.log(`${userIds.length} kullanıcı güncellendi`);
}
// Toplu işlem başına en fazla 500 işlem
4. Maliyetleri İzleyin
Firebase fiyatlandırması:
| Hizmet | Ücretsiz Katman | Ücretli |
|---|---|---|
| Firestore | Günde 50K okuma | 100K okuma başına 0.036 $ |
| Depolama | 5GB | GB başına 0.023 $ |
| Fonksiyonlar | 2M çağrı | 1M çağrı başına 0.40 $ |
| Kimlik Doğrulama | Ayda 10K | 100K başına 0.0055 $ |
Google Cloud Konsolu'nda bütçe uyarıları ayarlayın.
5. Servis Hesaplarını Güvenli Hale Getirin
// YANLIŞ: İstemci kodunda asla bunu yapmayın
admin.initializeApp({
credential: admin.credential.cert(require('./serviceAccountKey.json'))
});
// DOĞRU: Yalnızca sunucu ortamında kullanın
const serviceAccount = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT);
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
6. Çevrimdışı Senaryoları Ele Alın
// Çevrimdışı kalıcılığı etkinleştir (web)
import { enableMultiTabIndexedDbPersistence } from 'firebase/firestore';
enableMultiTabIndexedDbPersistence(db)
.catch((err) => {
if (err.code === 'failed-precondition') {
// Birden çok sekme açık
} else if (err.code === 'unimplemented') {
// Tarayıcı desteklemiyor
}
});
// Bağlantıyı dinle
import { onSnapshot } from 'firebase/firestore';
onSnapshot(doc(db, 'status', 'online'), (doc) => {
if (!doc.exists()) {
console.log('Çevrimdışısınız');
// Çevrimdışı kullanıcı arayüzünü göster
}
});
Yaygın Firebase API Sorunları ve Çözümleri
Sorun 1: İzin Reddedildi Hataları
Belirti: Error: 7 PERMISSION_DENIED
Neden: Güvenlik kuralları işlemi engelliyor
Düzeltme:
- Firebase Konsolu'ndaki kuralları kontrol edin
request.auth.uid'in beklenen kullanıcıyla eşleştiğini doğrulayın- Kuralları Kurallar Oyun Alanı ile test edin
Sorun 2: Belirteç Süre Sonları
Belirti: Error: ID token expired
Düzeltme:
// Belirteç yenilemeyi zorla
const user = auth.currentUser;
if (user) {
await user.getIdToken(true); // Yenilemeyi zorla
}
Sorun 3: Soğuk Başlangıç Gecikmesi
Belirti: Cloud Functions ilk çağrıda 2-5 saniye sürer
Düzeltme:
// Fonksiyonları zamanlanmış pinglerle sıcak tut
exports.keepWarm = onSchedule('every 60 seconds', async () => {
await fetch('https://fonksiyonunuz.cloudfunctions.net/health');
});
Sorun 4: Sorgu Boş Sonuçlar Döndürüyor
Belirti: Sorgu veri döndürmesi gerekirken boş dizi döndürüyor
Neden: Eksik indeks veya yanlış alan sırası
Düzeltme: Firestore Konsolu > İndeksler bölümünde gerekli bileşik indeksleri kontrol edin.
Gerçek Dünya Kullanım Durumları
Fintech Uygulaması: Gerçek Zamanlı İşlem Güncellemeleri
Bir ödeme girişimi, gerçek zamanlı işlem bildirimleri oluşturmak için Firebase Firestore'u kullandı. Bir ödeme işlendiğinde, Cloud Functions tüm bağlı yönetici panolarına 200 ms içinde güncellemeleri tetikler. Sonuç: "beklemede" işlemler hakkındaki destek taleplerinde %40 azalma.
E-ticaret: Envanter Senkronizasyonu
Bir çevrimiçi perakendeci, Firestore dinleyicileri kullanarak web, iOS ve Android genelinde envanteri senkronize eder. Stok değiştiğinde, tüm istemciler otomatik olarak güncellenir. Çevrimdışı kalıcılık, depo çalışanlarının bağlantı olmadan ürünleri taramasını sağlar ve yeniden bağlandığında otomatik senkronizasyon yapar.
SaaS: Çok Kiracılı Kimlik Doğrulama
Bir B2B platformu, rol tabanlı erişim için özel taleplerle Firebase Auth'u kullanır. Yönetici kullanıcılar, Firestore kiracı yapılandırmalarına göre doğrulama yapan Cloud Functions aracılığıyla yükseltilmiş izinler alır. Tek bir kod tabanı, izole edilmiş verilerle 500'den fazla kuruluşa hizmet verir.
Sonuç
Firebase API entegrasyonu dört temel hizmeti içerir:
- Kimlik Doğrulama: E-posta, Google, Apple JWT belirteçleriyle giriş
- Firestore: Gerçek zamanlı dinleyicilere ve güvenlik kurallarına sahip NoSQL veritabanı
- Cloud Functions: Olaylar veya HTTP tarafından tetiklenen sunucusuz arka uç
- Depolama: CDN dağıtımıyla dosya yüklemeleri
Kimlik doğrulama akışlarını, veritabanı işlemlerini, fonksiyon dağıtımını ve dosya yönetimini öğrendiniz. Üretim kalıplarını gördünüz: hata işleme, toplu işlem, çevrimdışı destek ve güvenlik.
SSS
Firebase ücretsiz mi?
Evet, Firebase cömert bir ücretsiz katmana (Spark Plan) sahiptir; 5 GB depolama alanı, günde 50 bin Firestore okuma, 2 milyon Cloud Function çağrısı ve ayda 10 bin Kimlik Doğrulama kullanıcısı içerir. Ücretli planlar (Blaze) kullandıkça öde fiyatlandırması kullanır.
Firebase'i mevcut veritabanlarıyla kullanabilir miyim?
Evet. PostgreSQL, MySQL veya MongoDB ile senkronize etmek için Firebase Uzantıları'nı kullanın. Veya mevcut sistemlerle entegre olmak için Cloud Functions'tan harici API'leri çağırın.
Firebase'den başka bir platforma nasıl geçiş yaparım?
Firestore dışa aktarma işlevlerini veya Firebase CLI'yi kullanarak verileri dışa aktarın. Büyük veri kümeleri için Dataflow dışa aktarma hattını kullanın. Geçiş karmaşıklığı veri yapınıza bağlıdır.
Firebase GraphQL'i destekliyor mu?
Doğal olarak değil. firestore-graphql gibi üçüncü taraf çözümleri kullanın veya Cloud Functions ve Apollo Server ile bir GraphQL katmanı oluşturun.
Firebase'i şirket içinde kullanabilir miyim?
Hayır. Firebase yalnızca Google Cloud tabanlıdır. Kendi kendine barındırılan alternatifler için Appwrite, Supabase veya Nhost'u düşünebilirsiniz.
100MB'den büyük dosya yüklemelerini nasıl hallederim?
Parçalama ile devam ettirilebilir yüklemeleri kullanın. Firebase SDK bunu otomatik olarak halleder. Çok büyük dosyalar için doğrudan Google Cloud Storage'ı imzalı URL'lerle kullanın.
Firestore sorgu limitlerini aşarsam ne olur?
Sorgular FAILED_PRECONDITION hatasıyla başarısız olur. Gerekli indeksleri ekleyin veya sorguları yeniden yapılandırın. Firestore, hata mesajında eksik indeksleri oluşturmak için doğrudan bağlantılar sağlar.
Firebase GDPR uyumlu mu?
Evet, Firebase GDPR uyumlu veri işleme sunar. Belirli bölgelerde veri yerleşimini etkinleştirin, kullanıcı verilerini dışa aktarma/silme işlemlerini uygulayın ve Google'ın Veri İşleme Ek Anlaşması'nı imzalayın.
