Flutter | Firestore Kullanarak Uygulama Geliştirmek (Provider ile)
Projeniz için uygun bir veritabanı arıyorsunuz. SQL sorguları , güvenlik , optimizasyon … derken bir fenalaşma geliyor değil mi?. Tam bu noktada imdadımıza yetişen bir kahraman “FIREBASE” çıkageliyor ve programcı diyor ki “NoSQL sen ne güzel şeysin”. Öhöm , ne diyor bu adam diye okudunuz sanırım kusura bakmayın. Bu yazımda birlikte Flutter’da ufak bir özlü sözler uygulaması geliştireceğiz ve Cloud Firestore kullanımını öğrenmiş olacağız. State management yöntemi olarak da Provider kullanmaya çalışacağız. O zaman başlayalım !.
Adım 1: Auth işlemlerini hallet.
Özlü söz yapısına geçmeden önce auth işlemlerini anlamak adına klasik bir email şifre girişi tasarlayalım. Bu kısım için öncelikle Firebase konsolunda Sign-in method kısmındaki email/password ayarını aktif etmeyi unutmayın !
Adım 1.1: Auth için servis sınıfını yaz.
service/firebase_auth_service.dart dosyasında oluşturduğumuz FirebaseAuthService, auth şlemleri için gerekli metotları yazacağımız sınıfımız. Bu dosyada kayıt işlemi için registerWithMail ve giriş işlemi için loginWithMail metotları bulunuyor.
FirebaseAuth.instance nesnesi üzerinden çağıracağımız createUserWithEmailAndPassword ve signInWithEmailAndPassword metotları ile Firebase’e giriş işlemlerimizi rahatlıkla hallediyoruz. Burada hiç bir giriş kontrolü vesaire yapmadığımızı görebilirsiniz. Örneğin sistemde varolan bir email ile kayıt olunmaya çalışıldığında Firebase size otomatik olarak bir exception döndürecektir. Bu exception’ı dilerseniz kayıt sayfanızda handle edip kullanıcıya bilgi gösterebilirsiniz. Bu uygulamada o tür ince detayları şimdilik atlayacağım.
Adım 1.2: Repository katmanı oluştur.
Servis katmanını soyutlamak için repository/my_repository.dart dosyasını oluşturduk. Aslında tam anlamıyla bir soyutlama sayılmaz çünkü uygulamayı basit tutmak adına herhangi bir abstract class kalıtımı uygulamadım. Şuan aynı metotları içeren farklı bir sınıf sadece :). Repository pattern’i için şu makaleye göz atabilirsiniz.
Adım 1.3: ViewModel yapısını kur.
ChangeNotifier’dan kalıtım alan view_model/motto_view_model.dart dosyamızdaki MottoViewModel sınıfı state değişikliklerini handle edip bu state bilgisi ile arayüzümüzü güncelleyeceğimiz sınıfımız. Uygulamamızda olabilecek durumları enum tipindeki AppState nesnesinde tutuyoruz ve state değişikliğini dinlemesi için notifyListeners() metodunu çağırıyoruz. Kayıt olma ve giriş metotlarını eklediğimiz ViewModel yapısı şu şekilde:
Auth metotlarımızı yazdık. Kullanıcı bilgileriyle ilgili işlemleriniz olacaksa eğer bir kullanıcı modeli tasarlamanız çok daha iyi olacaktır.
Şimdi geleliim uygulama senaryosuna..
Öncelikle kullanıcı uygulamaya giriş yaptığında anasayfada o an veritabanında olan tüm mottoları görebilsin. Motto eklemek için anasayfada bir buton olsun ve bir form ekranına yönlendirilsin. Ayrıca anasayfada kullanıcı kendisine ait olan mottoları silebilsin ve güncelleyebilsin fakat başka bir hesaba ait olan mottolara bunu yapamasın. Bence yeterli :). Şimdi motto kısmına..
Adım 2: Motto modelini oluştur.
Motto’nun hangi kullanıcıya ait olduğunu bilebilmemiz için modelimizde kullanıcı uuid bilgisini ve motto docs üzerinde işlem yapabilmek için o an oluşan mottoid bilgisini modelimizde tutuyoruz. Diğer alanlar ise ekranda göstermek istediğimiz kısımlardan oluşmakta.
Adım 2.1: Motto modeli için servis sınıfı oluştur ve operasyonları tanımla.
CRUD işlemlerimiz için service/firestore_service.dart içinde FireStoreService sınıfımızı tanımlıyoruz ve motto eklemek için addDataToFirestore metodumuzu yazıyoruz. Oluşturmak istediğimiz collection yolunu veriyoruz ve random bir id generate etmesi için doc() metodunu çağırıyoruz.
Tüm mottoları okumak için collection referansından bir QuerySnapshot döndüren nesneyi readDataFromFirestore metodunda döndürüyoruz. Iterasyonu ViewModel içerisinde yapacağız.
Motto silmek için removeData metodunda silinecek mottonun id’sini parametre olarak doc() metoduna geçiyor ve delete() metodunu çağırıyoruz.
Motto güncellemek için silmedekine benzer bir mantıkla updateData metodunda silinecek mottonun id’sini doc() metoduna ve güncellenecek olan değerleri ise bir map şeklinde update() metoduna geçiyoruz.
Adım 2.2: ViewModel’i güncelle.
Repository kısmına da servis metodlarımızı ekliyoruz ve ViewModel sınıfımıza geçiyoruz. Okuduğumuz verileri Motto modeli tipinde veriler tutan mottos listesi içerisinde saklayacak ve arayüzümüzde ViewModel vasıtasıyla verilerimize bu listeden erişebileceğiz. ViewModel sınıfına eklediğimiz metodlar şu şekilde:
Okuma işleminde dikkat edilmesi gereken bir husus listemizi clear() metodu ile temizlemek olacaktır. Temizlemezsek eğer her anasayfa’ya geçişimizde liste tekrar aynı verilerle doldurulur. Bu da pek hoş gözükmez sanırım :).
Şimdi gelelim bu verileri nasıl göstereceğimize ,
Consumer ile ViewModel nesnesimize erişip o anki state’i kontrol ediyoruz. Eğer yükleme anında isek bize bir CircularProgressIndicator dönüyor, diğer durumlarda ise ListView.builder kullandım. Hata durumunu da kontrol edip bir mesaj gösterebilirdik.
Burada ListView elemanlarımızı kaydırarak bazı işlemler yapmamızı sağlayan flutter_slidable paketini kullanıyoruz. Burada eleman üzerinde bir sağa kaydırma durumunda karşımıza silme ve güncelleme için iki adet seçenek çıkartıyor. Silme işleminde yapmamız gereken tek şey ViewModel nesnesi üzerinden removeMotto metodunu çağırmak. Güncelleme işlemi için de motto verimizi girdiğimiz sayfaya bir argüman ile birlikte yönlendirme yapıyoruz. Yolladığımız argümanın amacı ise o sayfaya güncelleme için mi yoksa yeni bir motto eklemek için mi girdiğimizi kontrol etmek. Duruma göre de ekranda farklı düzenlemeler yapıyoruz.
Ve mutlu son.. :)
Kodun tamamı için repo’yu inceleyebilirsiniz -> https://github.com/SamedHrmn/flutter-works/tree/master/firebase-work
Umarım faydalı olmuştur. Başka yazılarda görüşmek üzere :).
Faydalandığım kaynaklar: