Ders İçeriği
Firebase, Google tarafından geliştirilen bir mobil ve web uygulama geliştirme platformudur. Arka uç hizmetleri (backend-as-a-service - BaaS) sunarak geliştiricilerin sunucu tarafı kod yazma ihtiyacını azaltır ve uygulama geliştirme sürecini hızlandırır. Flutter ile Firebase entegrasyonu oldukça kolaydır ve birçok yaygın arka uç ihtiyacını karşılar.
2.1. Firebase Projesi Kurulumu
Flutter uygulamanızı Firebase ile entegre etmek için aşağıdaki adımları izlemeniz gerekir:
1.Firebase Konsolu Üzerinden Proje Oluşturma:
•Firebase Konsolu adresine gidin ve Google hesabınızla oturum açın.
•Proje Ekle butonuna tıklayın.
•Projenize bir isim verin ve devam edin. Google Analytics ayarlarını isteğinize göre yapılandırın.
•Projeniz oluşturulduktan sonra, Firebase konsolunda projenizin ana sayfasına yönlendirileceksiniz.
2.Uygulamanızı Firebase Projesine Ekleme:
•Firebase projenizin ana sayfasında, uygulamanızın platformuna (iOS, Android, Web) göre ilgili simgeye tıklayın (örneğin, Android için Android simgesi).
•Android için:
•Uygulamanızın paket adını (package name) girin. Bu, android/app/src/main/AndroidManifest.xml dosyasında package özniteliğinde bulunur (örneğin, com.example.my_app).
•Uygulamanızın SHA-1 sertifika parmak izini (fingerprint) ekleyin (isteğe bağlı ama bazı Firebase hizmetleri için gereklidir, örneğin telefonla kimlik doğrulama). Bunu almak için terminalde aşağıdaki komutu çalıştırabilirsiniz:
•google-services.json dosyasını indirin ve Flutter projenizin android/app/ dizinine yerleştirin.
•Firebase konsolundaki talimatları izleyerek build.gradle dosyalarınızda gerekli değişiklikleri yapın (proje seviyesi ve uygulama seviyesi build.gradle).
•iOS için:
•Uygulamanızın Bundle ID'sini girin. Bu, Xcode'da projenizin General sekmesinde Bundle Identifier altında bulunur.
•GoogleService-Info.plist dosyasını indirin ve Xcode kullanarak projenizin Runner klasörüne sürükleyip bırakın. Hedef olarak Runner'ı seçtiğinizden ve Copy items if needed seçeneğinin işaretli olduğundan emin olun.
•Firebase konsolundaki talimatları izleyerek AppDelegate.swift veya AppDelegate.m dosyanızda gerekli değişiklikleri yapın.
3.FlutterFire CLI Kurulumu ve Kullanımı:
Firebase ile Flutter uygulamalarını entegre etmenin en kolay yolu FlutterFire CLI kullanmaktır. Bu araç, Firebase projenizi Flutter projenize bağlamak için gerekli yapılandırma dosyalarını otomatik olarak oluşturur.
•Terminalde aşağıdaki komutu çalıştırarak FlutterFire CLI'ı yükleyin:
•Firebase'e giriş yapın:
•Flutter projenizin kök dizininde aşağıdaki komutu çalıştırın:
4.Firebase Core Paketini Ekleme:
Tüm Firebase hizmetlerini kullanabilmek için firebase_core paketini pubspec.yaml dosyanıza eklemeniz gerekir:
5.Firebase'i Başlatma:
Uygulamanızın main() fonksiyonunda Firebase'i başlatmanız gerekir:
Bu adımları tamamladıktan sonra, Flutter uygulamanız Firebase ile iletişim kurmaya hazır olacaktır. Artık Firebase'in sunduğu çeşitli hizmetleri kullanmaya başlayabilirsiniz.
2.2. Firestore (NoSQL Veritabanı)
Cloud Firestore, Firebase'in esnek, ölçeklenebilir bir NoSQL bulut veritabanıdır. Uygulamanız için gerçek zamanlı veri senkronizasyonu ve çevrimdışı destek sunar. Veriler, koleksiyonlar ve belgeler halinde düzenlenir.
Öncelikle cloud_firestore paketini pubspec.yaml dosyanıza ekleyin:dependencies:
flutter:
sdk: flutter
cloud_firestore: ^4.13.3 # En güncel sürümü kullanın
Sonra flutter pub get komutunu çalıştırın.
Kullanım Örneği:import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class FirestoreExample extends StatelessWidget {
const FirestoreExample({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Firestore Örneği')),
body: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('users').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Hata: ${snapshot.error}');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
return ListTile(
title: Text(data['name']),
subtitle: Text(data['email']),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
FirebaseFirestore.instance.collection('users').doc(document.id).delete();
},
),
onTap: () {
// Güncelleme örneği
FirebaseFirestore.instance.collection('users').doc(document.id).update({
'name': '${data['name']} (Güncellendi)'
});
},
);
}).toList(),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Yeni kullanıcı ekle
FirebaseFirestore.instance.collection('users').add({
'name': 'Yeni Kullanıcı ${DateTime.now().second}',
'email': 'yeni.kullanici${DateTime.now().second}@example.com',
'age': 30,
});
},
child: const Icon(Icons.add),
),
);
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(); // Firebase'i başlat
runApp(const MaterialApp(home: FirestoreExample()));
}
Temel Firestore İşlemleri:
•Veri Ekleme (add()): Yeni bir belge ekler ve otomatik olarak bir ID oluşturur.
•Veri Okuma (get() / snapshots()):
•get(): Bir kerelik veri okuma için kullanılır.
•snapshots(): Gerçek zamanlı güncellemeleri dinlemek için kullanılır. Veritabanında bir değişiklik olduğunda otomatik olarak yeni veriyi sağlar.
•Veri Güncelleme (update()): Mevcut bir belgedeki belirli alanları günceller.
•Veri Silme (delete()): Bir belgeyi siler.
2.3. Firebase Authentication (Kullanıcı Kimlik Doğrulama)
Firebase Authentication, uygulamanıza güvenli ve kolay bir şekilde kullanıcı kimlik doğrulama özellikleri eklemenizi sağlar. E-posta/şifre, Google, Facebook, telefon numarası gibi birçok farklı kimlik doğrulama yöntemini destekler.
Öncelikle firebase_auth paketini pubspec.yaml dosyanıza ekleyin:dependencies:
flutter:
sdk: flutter
firebase_auth: ^4.15.3 # En güncel sürümü kullanın
Sonra flutter pub get komutunu çalıştırın.
Kullanım Örneği (E-posta/Şifre ile):import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
class AuthScreen extends StatefulWidget {
const AuthScreen({Key? key}) : super(key: key);
@override
State<AuthScreen> createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
final FirebaseAuth _auth = FirebaseAuth.instance;
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
String? _message;
Future<void> _register() async {
try {
await _auth.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
setState(() {
_message = 'Kayıt başarılı!';
});
} on FirebaseAuthException catch (e) {
setState(() {
_message = e.message;
});
}
}
Future<void> _signIn() async {
try {
await _auth.signInWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
setState(() {
_message = 'Giriş başarılı!';
});
} on FirebaseAuthException catch (e) {
setState(() {
_message = e.message;
});
}
}
Future<void> _signOut() async {
await _auth.signOut();
setState(() {
_message = 'Çıkış yapıldı.';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Firebase Auth Örneği')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: _emailController,
decoration: const InputDecoration(labelText: 'E-posta'),
keyboardType: TextInputType.emailAddress,
),
TextField(
controller: _passwordController,
decoration: const InputDecoration(labelText: 'Şifre'),
obscureText: true,
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: _register,
child: const Text('Kayıt Ol'),
),
ElevatedButton(
onPressed: _signIn,
child: const Text('Giriş Yap'),
),
],
),
const SizedBox(height: 20),
if (_message != null) Text(_message!),
const SizedBox(height: 20),
StreamBuilder<User?>(
stream: _auth.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
User? user = snapshot.data;
if (user == null) {
return const Text('Giriş yapılmadı.');
} else {
return Column(
children: [
Text('Giriş yapıldı: ${user.email}'),
ElevatedButton(
onPressed: _signOut,
child: const Text('Çıkış Yap'),
),
],
);
}
}
return const CircularProgressIndicator();
},
),
],
),
),
);
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MaterialApp(home: AuthScreen()));
}
Temel Kimlik Doğrulama İşlemleri:
•Kayıt Olma: createUserWithEmailAndPassword()
•Giriş Yapma: signInWithEmailAndPassword()
•Çıkış Yapma: signOut()
•Kullanıcı Durumu Dinleme: authStateChanges() stream'i ile kullanıcının giriş/çıkış durumunu gerçek zamanlı olarak takip edebilirsiniz.
2.4. Firebase Storage (Dosya Depolama)
Firebase Storage, kullanıcı tarafından oluşturulan içerikleri (resimler, videolar, belgeler vb.) depolamak için tasarlanmış güçlü ve ölçeklenebilir bir bulut depolama hizmetidir. Güvenlik kuralları ile erişimi kontrol edebilirsiniz.
Öncelikle firebase_storage paketini pubspec.yaml dosyanıza ekleyin:dependencies:
flutter:
sdk: flutter
firebase_storage: ^11.5.3 # En güncel sürümü kullanın
image_picker: ^1.0.4 # Resim seçmek için
Sonra flutter pub get komutunu çalıştırın.
Kullanım Örneği (Resim Yükleme):import 'package:flutter/material.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
class StorageExample extends StatefulWidget {
const StorageExample({Key? key}) : super(key: key);
@override
State<StorageExample> createState() => _StorageExampleState();
}
class _StorageExampleState extends State<StorageExample> {
final FirebaseStorage _storage = FirebaseStorage.instance;
String? _imageUrl;
double _uploadProgress = 0.0;
Future<void> _uploadImage() async {
final ImagePicker picker = ImagePicker();
final XFile? image = await picker.pickImage(source: ImageSource.gallery);
if (image != null) {
File file = File(image.path);
String fileName = DateTime.now().millisecondsSinceEpoch.toString();
Reference ref = _storage.ref().child('images/$fileName.jpg');
UploadTask uploadTask = ref.putFile(file);
uploadTask.snapshotEvents.listen((TaskSnapshot snapshot) {
setState(() {
_uploadProgress = snapshot.bytesTransferred / snapshot.totalBytes;
});
});
await uploadTask.whenComplete(() async {
String downloadUrl = await ref.getDownloadURL();
setState(() {
_imageUrl = downloadUrl;
_uploadProgress = 0.0; // Yükleme tamamlandı, sıfırla
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Resim başarıyla yüklendi!')),
);
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Firebase Storage Örneği')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_imageUrl == null
? const Text('Resim yüklenmedi.')
: Image.network(_imageUrl!, height: 200),
const SizedBox(height: 20),
if (_uploadProgress > 0 && _uploadProgress < 1)
LinearProgressIndicator(value: _uploadProgress),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _uploadImage,
child: const Text('Resim Yükle'),
),
],
),
),
);
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MaterialApp(home: StorageExample()));
}
2.5. Firebase Cloud Messaging (Bildirimler)
Firebase Cloud Messaging (FCM), uygulamalarınıza güvenilir ve ücretsiz bir şekilde bildirim göndermenizi sağlayan platformlar arası bir mesajlaşma çözümüdür. Kullanıcılara hedeflenmiş bildirimler gönderebilir, uygulama içi mesajlar gösterebilir veya arka planda veri gönderebilirsiniz.
Öncelikle firebase_messaging paketini pubspec.yaml dosyanıza ekleyin:dependencies:
flutter:
sdk: flutter
firebase_messaging: ^14.7.10 # En güncel sürümü kullanın
Sonra flutter pub get komutunu çalıştırın.
Kullanım Örneği:import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// Arka planda gelen bildirimleri işleyin
print(
Handling a background message: ${message.messageId}");
}
class PushNotificationScreen extends StatefulWidget {
const PushNotificationScreen({Key? key}) : super(key: key);
@override
State<PushNotificationScreen> createState() => _PushNotificationScreenState();
}
class _PushNotificationScreenState extends State<PushNotificationScreen> {
String _message = "";
@override
void initState() {
super.initState();
_initializeFCM();
}
Future<void> _initializeFCM() async {
// Arka plan mesaj işleyicisini kaydet
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
// Uygulama ön plandayken gelen mesajları dinle
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print("Got a message whilst in the foreground!");
print("Message data: ${message.data}");
if (message.notification != null) {
setState(() {
_message = "Ön Plan Bildirimi: ${message.notification!.title} - ${message.notification!.body}";
});
print("Message also contained a notification: ${message.notification}");
}
});
// Uygulama kapalıyken veya arka plandayken bildirim tıklandığında
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print("A new onMessageOpenedApp event was published!");
setState(() {
_message = "Uygulama Açıldı: ${message.notification!.title} - ${message.notification!.body}";
});
});
// Cihazın FCM tokenını al
String? token = await FirebaseMessaging.instance.getToken();
print("FCM Token: $token");
setState(() {
_message = "FCM Token: $token";
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("FCM Bildirim Örneği")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
"Bildirim Durumu:",
style: TextStyle(fontSize: 20),
),
Text(
_message,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 16, color: Colors.blueGrey),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
String? token = await FirebaseMessaging.instance.getToken();
setState(() {
_message = "Yeniden Alınan FCM Token: $token";
});
},
child: const Text("Tokenı Yenile"),
),
],
),
),
);
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MaterialApp(home: PushNotificationScreen()));
}
FCM Kullanım Adımları:
1.Firebase Projesi Kurulumu: Firebase konsolunda projenizi oluşturun ve uygulamanızı kaydedin (yukarıdaki 2.1 bölümüne bakın).
2.firebase_messaging Paketini Ekleme: pubspec.yaml dosyasına ekleyin.
3.Firebase Başlatma: main() fonksiyonunda Firebase.initializeApp() çağrısını yapın.
4.Token Alma: FirebaseMessaging.instance.getToken() ile cihazın benzersiz FCM tokenını alabilirsiniz. Bu tokenı sunucunuza kaydederek belirli cihazlara bildirim gönderebilirsiniz.
5.Mesajları Dinleme:
•FirebaseMessaging.onMessage.listen(): Uygulama ön plandayken gelen bildirimleri dinler.
•FirebaseMessaging.onBackgroundMessage(): Uygulama arka plandayken veya kapalıyken gelen bildirimleri işlemek için üst düzey bir fonksiyon tanımlamanız gerekir.
•FirebaseMessaging.onMessageOpenedApp.listen(): Uygulama kapalıyken veya arka plandayken bir bildirim tıklandığında tetiklenir.
FCM, uygulamanızın kullanıcılarla etkileşimini artırmak ve önemli bilgileri anında iletmek için güçlü bir araçtır.