Firebase Firestore Database

By | 19 Mayıs 2021

Bir önceki dersimizde Firebase ile ilgili 3 temel konuya değineceğimizi belirtmiştim ve ilki olan Authentication konusunu detaylıca işledik. Şimdi sıra geldi 2. Ve biraz uzun sürecek olan Firestore konusuna.

Firestore’den önce RealtimeDatabase vardı ve veriler birbirlerinin çocukları konumunda yer almaktaydı. Firestore mantığında ise verileri dosyalar ve koleksiyonlar içerisinde tutuyoruz. Bu sebepten iki önemli anahtar kelimeyi sıkça kullanacağız. Bunlar;

  • DocumentReference: Belli bir dosya üzerinde işlemler yapılacağı zaman
  • CollectionReference: Bir koleksiyon içerisinde işlemler yapılacağı zaman

Aşağıda örnek bir veri tabanı modeli yer almakta.

  1. En üst veya kök kısımda koleksiyon yer alır. Burada birden fazla koleksiyon yer alabilir.
  2. Koleksiyonların içerisinde belgeler(dosyalar) yer alır.
  3. Belgelerin içerisinde tekrardan koleksiyonlar yer alabilir.
  4. Belgelerin içerisinde genellikle içerikler yer alır.

DocumentReference ve CollectionReference’i nerede kullanacağımızı az çok kavramış olduk. Şimdi kullanımına geçelim.

Firebase bağlantısını sağlamayı ve gerekli kütüphaneleri nasıl ekleyebileceğimizi bir önceki Firebase Authentication dersimizde görmüştük. Farklı olarak yapılacak tek yer Assistant kısmında Authentication yerine Cloud Firestore’i bulup ilerlemek.

Firebase kullanacağımızdan dolayı manifest dosyasında internet iznini vermemiz gerekecektir. Bir önceki dersimizden farklı olarak 2 şey daha yapacağız aslında.

  1. Verilerimizin tutulacağı sunucuyu(Bölge) seçmek
  2. Verilerin okuma ve yazma yetkisini belirlemek.

Bunun için aşağıdaki adımları takip ederek gerekli işlemleri yapabilirsiniz.

Burada bize ön tanımlı olarak gelen bir ayar bulunmakta. Bunu nasıl değiştireceğimizi 2. Adımda birazdan göstereceğim(Verilerin okuma ve yazma yetkisini belirlemek). Şimdilik böyle Next diyin.

Bu kısımda bölgeyi seçiyoruz. Fark etmez ama Avrupa bölgesinde bir yer olması milisaniyelik bir oranla size hız kazandırabilir. Uyarı kısmında bu ayarı daha sonradan değiştiremeyeceğimizi de özellikle belirtmiş.

Şimdi sıra geldi okuma yazma yetkisini belirlemek.

Resimde işaretlediğim yeri aşağıdaki gibi değiştirin. Böylelikle veriler üzerinde okuma ve yazma yetkisini kullanıcıların hesabının olup olmadığına bakarak gerçekleştirecektir.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if
          request.auth != null;
    }
  }
}

Aşağıda geliştireceğimiz uygulamanın çıktıları ve kodları yer almaktadır.

activity_home.xml dosyası

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="25dp"
    tools:context=".HomeActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="You are now in the home screen"
        android:textAlignment="center"
        android:textSize="24sp" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:onClick="exit"
        android:padding="15dp"
        android:text="Exit"
        android:textSize="20sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginTop="30dp"
        android:padding="20dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="DocumentReference"
            android:textAlignment="center"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="save"
            android:padding="20dp"
            android:text="Save" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="getData"
            android:padding="20dp"
            android:text="Get Data" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginTop="30dp"
        android:padding="20dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="CollectionReference"
            android:textAlignment="center"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="saveCol"
            android:padding="20dp"
            android:text="Save" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="getDataCol"
            android:padding="20dp"
            android:text="Get Data" />

    </LinearLayout>

</LinearLayout>

HomeActivity.kt dosyası

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.CollectionReference
import com.google.firebase.firestore.DocumentReference
import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.FirebaseFirestore
import com.mrcaracal.firebaseuseroperations.databinding.ActivityHomeBinding
import java.util.*
import kotlin.collections.HashMap

class HomeActivity : AppCompatActivity() {

    private lateinit var binding: ActivityHomeBinding
    private lateinit var auth: FirebaseAuth
    private lateinit var firestore: FirebaseFirestore
    private lateinit var documentReference: DocumentReference
    private lateinit var datas: HashMap<String, String>
    private lateinit var collectionReference: CollectionReference

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityHomeBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        auth = FirebaseAuth.getInstance()
        firestore = FirebaseFirestore.getInstance()
        documentReference = firestore.collection("Users").document()
        collectionReference = firestore.collection("Users")

        datas = HashMap()
        datas.put("name", "Caracal")
        datas.put("country", "Turkey")
    }

    fun exit(view: View) {
        auth.signOut()
        val intent = Intent(this, SignInActivity::class.java)
        startActivity(intent)
        finish()
    }

    fun save(view: View) {
        documentReference.set(datas)
            .addOnSuccessListener {
                Toast.makeText(applicationContext, "Successful", Toast.LENGTH_SHORT).show()
            }
            .addOnFailureListener {
                Toast.makeText(applicationContext, "Unsuccessful", Toast.LENGTH_SHORT).show()
            }
    }

    fun getData(view: View) {
        documentReference.get()
            .addOnCompleteListener{ mrcaracal ->
                if (mrcaracal.isSuccessful){
                    var documentSnapshot = mrcaracal.getResult()
                    if (documentSnapshot!!.exists()){
                        var data_name = documentSnapshot.get("name")
                        var data_country = documentSnapshot.get("country")
                        Toast.makeText(applicationContext, "Name: "+ data_name, Toast.LENGTH_SHORT).show()
                    }
                }
            }
            .addOnFailureListener {
                Toast.makeText(applicationContext, "Unsuccessful", Toast.LENGTH_SHORT).show()
            }
    }

    fun saveCol(view: View) {
        collectionReference.add(datas)
            .addOnSuccessListener {
                Toast.makeText(applicationContext, "Successful", Toast.LENGTH_SHORT).show()
            }
            .addOnFailureListener {
                Toast.makeText(applicationContext, "Unsuccessful", Toast.LENGTH_SHORT).show()
            }
    }

    fun getDataCol(view: View) {
        collectionReference.get()
            .addOnCompleteListener { mrcaracal ->
                if (mrcaracal.isSuccessful){
                    var querySnapshot = mrcaracal.getResult()
                    if (querySnapshot != null) {
                        var i: Int = 1
                        for (documentSnapshot: DocumentSnapshot in querySnapshot){
                            var map: Map<String, Objects> = documentSnapshot.getData() as Map<String, Objects>
                            var str_name: String = map.get("name").toString()
                            var str_country: String = map.get("country").toString()
                            Toast.makeText(applicationContext, "${i}. Name: "+ str_name, Toast.LENGTH_SHORT).show()
                            i++
                        }
                    }
                }
            }
    }
}

DocumentReference Kullanımı

Neler yaptığımıza bakacak olursak;

private lateinit var documentReference: DocumentReference
private lateinit var datas: HashMap<String, String>

Burada DocumentReference’i ve verilerimizi yazdırmak için bir HashMap oluşturduk. Gerekli tanımlamalarını da onCreate() içerisinde aşağıdaki gibi yaptık.

documentReference = firestore.collection("Users").document()

datas = HashMap()
datas.put("name", "Caracal")
datas.put("country", "Turkey")

Burada documentReference ile veri tabanımızda Users isminde bir koleksiyon ve içine de bir belge oluşturmasını söyledik. Eğer document(“birseyyazdik”) içine bir şeyler yazsaydık verdiğimiz isimde bir dosya oluşturacaktı. Herhangi bir şey yazamayarak random karakterlerle bir belge oluşturuldu.

HashMap kısmında da elle bir veri girmiş olduk. Bu yapıyı kullanarak veri tabanımıza veri ekleyeceğiz. İleriki derslerimizde model oluşturarak yapacağız bunu. Kullanıcıdan da veri alarak nasıl ekleyebileceğimizi görmüş olacağız.

Save butonuna tıklanması durumunda

fun save(view: View) {
        documentReference.set(datas)
            .addOnSuccessListener {
                Toast.makeText(applicationContext, "Successful", Toast.LENGTH_SHORT).show()
            }
            .addOnFailureListener {
                Toast.makeText(applicationContext, "Unsuccessful", Toast.LENGTH_SHORT).show()
            }
    }

documentReference ile datas isimli HashMap’e yazdırdığımız verileri set() ile yazdırmış olduk. İşlemin gerçekleşip gerçekleşmediğini de addOnSuccessListener ve addOnFailureListener’la kontrol ettik.

Get Data butonuna tıklanması durumunda

fun getData(view: View) {
        documentReference.get()
            .addOnCompleteListener{ mrcaracal ->
                if (mrcaracal.isSuccessful){
                    var documentSnapshot = mrcaracal.getResult()
                    if (documentSnapshot!!.exists()){
                        var data_name = documentSnapshot.get("name")
                        var data_country = documentSnapshot.get("country")
                        Toast.makeText(applicationContext, "Name: "+ data_name, Toast.LENGTH_SHORT).show()
                    }
                }
            }
            .addOnFailureListener {
                Toast.makeText(applicationContext, "Unsuccessful", Toast.LENGTH_SHORT).show()
            }
    }

documentReference ile get() kullanarak verilerimizi çektik. Çektiğimiz verileri göstermek için addOnCompleteListener’da bize geri veri döndüren mrcaracal ile gerekli kontrolleri ve atamaları yaptık.

mrcaracal kısmında istediğinizi yazabilirsiniz. Ön tanımlı olarak it gelecektir. Bilginiz olsun.

documentSnapshot.get("name")

HashMap yapısında ve firebase’de verilerin key-value mantığı ile tutulduğunu bildiğimize göre burada get(key) ile istediğimiz veriyi alabiliriz.

CollectionReference Kullanımı

Dersin başında DocumentReference ve CollectionReference’nin tanımını yaptıktan sona DocumentReference’i anlattım. Belge üzerinde istediğimiz işlemi yapıp verileri set() ile yazdırıp get() ile aldık. CollectionReference’te ise verileri add() ile ekleyip get() ile çekeceğiz ama doğrudan bir belgeyle uğraşmak yerine belgelerin de içinde yer aldığı koleksiyonla uğraşacağız.

Neler yaptığımıza bakacak olursak;

private lateinit var collectionReference: CollectionReference

ve onCreate() içerisinde

collectionReference = firestore.collection("Users")

gerekli tanımlamaları yaptıktan sonra artık artık CollectionReference’i kullanabiliriz.

CollectionReference için hazırladığımız Save butonuna basıldığında

fun saveCol(view: View) {
        collectionReference.add(datas)
            .addOnSuccessListener {
                Toast.makeText(applicationContext, "Successful", Toast.LENGTH_SHORT).show()
            }
            .addOnFailureListener {
                Toast.makeText(applicationContext, "Unsuccessful", Toast.LENGTH_SHORT).show()
            }
    }

collectionReference kullanarak random bir belge oluşturduk ve add(datas) ile verilerimizi içine yazdırdık. Ardından addOnSuccessListenr ve addOnFailureListener ile işlemin kontrolünü yaptık.

CollectionReference için hazırladığımız Get Data butonuna basıldığında

fun getDataCol(view: View) {
        collectionReference.get()
            .addOnCompleteListener { mrcaracal ->
                if (mrcaracal.isSuccessful){
                    var querySnapshot = mrcaracal.getResult()
                    if (querySnapshot != null) {
                        var i: Int = 1
                        for (documentSnapshot: DocumentSnapshot in querySnapshot){
                            var map: Map<String, Objects> = documentSnapshot.getData() as Map<String, Objects>
                            var str_name: String = map.get("name").toString()
                            var str_country: String = map.get("country").toString()
                            Toast.makeText(applicationContext, "${i}. Name: "+ str_name, Toast.LENGTH_SHORT).show()
                            i++
                        }
                    }
                }
            }
    }

collectionReference ile get() kullanarak verilerimizi çektik. Çektiğimiz verileri göstermek için addOnCompleteListener’da bize geri veri döndüren mrcaracal ile gerekli kontrolleri ve atamaları yaptık.

Koleksiyonlar içerisinde birden fazla belge olabileceğinden for döngüsü ile tüm belgelerin içine girdik ve verilerimizi kullanıcıya gösterdik.

Bir sonraki dersimiz bu dersin devamı niteliğinde olacaktır. Silme, güncelleme, birçok veriyi listeleme ve filtreleme gibi işlemleri nasıl yapabileceğimizi öğreneceğiz.

İyi günler dilerim 🙂

3 thoughts on “Firebase Firestore Database

  1. Pingback: Firebase Firestore Database -2 - Mr. Caracal - Kayıt, silme ve filtreleme

  2. RÜZGAR ÜREN

    i just meet with your plog and it looks like perfect. thanks for your work .

    Reply

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir