Verileri Kaydetme

Veri tasarrufu yapmanın yolları

PUT Verileri tanımlanmış bir yola (ör. fireblog/users/user1/<data>) yazma veya değiştirme
YAMA Tüm verileri değiştirmeden tanımlı bir yolun bazı anahtarlarını güncelleyin.
POST Firebase veritabanımızdaki veri listesine ekleme. Her POST isteği gönderdiğimizde Firebase istemcisi, fireblog/users/<unique-id>/<data> gibi benzersiz bir anahtar oluşturur.
SİL Verileri belirtilen Firebase veritabanı referansından kaldırır.

PUT ile veri yazma

REST API üzerinden temel yazma işlemi PUT'dır. Veri kaydetmeyi göstermek için gönderileri ve kullanıcıları olan bir blog uygulaması oluşturacağız. Uygulamamızla ilgili tüm veriler, Firebase veritabanı URL'si olan `https://docs-examples.firebaseio.com/fireblog` adresindeki `fireblog` yolu altında depolanır.

Öncelikle Firebase veritabanımıza bazı kullanıcı verileri kaydederek başlayalım. Her kullanıcıyı benzersiz bir kullanıcı adıyla saklarız. Ayrıca kullanıcının tam adını ve doğum tarihini de saklarız. Her kullanıcının benzersiz bir kullanıcı adı olacağından, anahtarımız zaten olduğundan ve yeni bir anahtar oluşturmamıza gerek olmadığından burada POST yerine PUT kullanmak mantıklıdır.

PUT kullanarak Firebase veritabanımıza dize, sayı, boole, dizi veya herhangi bir JSON nesnesi yazabiliriz. Bu örnekte, işleme bir nesne ileteceğiz:

curl -X PUT -d '{
  "alanisawesome": {
    "name": "Alan Turing",
    "birthday": "June 23, 1912"
  }
}' 'https://docs-examples.firebaseio.com/fireblog/users.json'

Bir JSON nesnesi veritabanına kaydedildiğinde nesne özellikleri, iç içe yerleştirilmiş şekilde alt konumlara otomatik olarak eşlenir. Yeni oluşturulan düğüme gidersek "Alan Turing" değerini görürüz. Verileri doğrudan bir alt konuma da kaydedebiliriz:

curl -X PUT -d '"Alan Turing"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/name.json'
curl -X PUT -d '"June 23, 1912"' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome/birthday.json'

Yukarıdaki iki örnekte (değeri bir nesneyle aynı anda yazma ve değerleri alt konumlara ayrı ayrı yazma) Firebase veritabanımıza aynı veriler kaydedilir:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing"
    }
  }
}

Başarılı bir istek, 200 OK HTTP durum koduyla belirtilir ve yanıt, veritabanına yazdığımız verileri içerir. İlk örnek, verileri izleyen istemcilerde yalnızca bir etkinliği tetiklerken ikinci örnek iki etkinliği tetikler. Kullanıcı yolunda zaten veri varsa ilk yaklaşımın bu verilerin üzerine yazacağını, ancak ikinci yöntemin diğer alt öğeleri değiştirmeden yalnızca her bir ayrı alt düğümün değerini değiştireceğini unutmayın. PUT, JavaScript SDK'mızdaki set() ile eşdeğerdir.

Verileri PATCH ile güncelleme

PATCH isteğini kullanarak, mevcut verilerin üzerine yazmadan belirli alt öğeleri bir konumda güncelleyebiliriz. Turing'in kullanıcı verilerine PATCH isteğiyle takma adını ekleyelim:

curl -X PATCH -d '{
  "nickname": "Alan The Machine"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

Yukarıdaki istek, nickname öğesini name veya birthday alt öğelerini silmeden alanisawesome nesnemize yazar. Burada PUT isteği gönderseydik name ve birthday isteğe dahil edilmediği için silinecekti. Firebase veritabanımızdaki veriler artık şu şekilde görünüyor:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    }
  }
}

Başarılı bir istek 200 OK HTTP durum koduyla belirtilir ve yanıtta, veritabanına yazılan güncellenmiş veriler yer alır.

Firebase, çok yollu güncellemeleri de destekler. Bu, PATCH artık Firebase veritabanınızdaki birden fazla konumda değerleri aynı anda güncelleyebileceği anlamına gelir. Bu güçlü özellik, verilerinizi normalleştirmenize yardımcı olur. Çok yollu güncellemeleri kullanarak hem Alan'a hem de Grace'e aynı anda takma ad ekleyebiliriz:

curl -X PATCH -d '{
  "alanisawesome/nickname": "Alan The Machine",
  "gracehopper/nickname": "Amazing Grace"
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

Bu güncellemeden sonra Alan ve Grace'in takma adları eklendi:

{
  "users": {
    "alanisawesome": {
      "date_of_birth": "June 23, 1912",
      "full_name": "Alan Turing",
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "date_of_birth": "December 9, 1906",
      "full_name": "Grace Hopper",
      "nickname": "Amazing Grace"
    }
  }
}

Nesneleri yollarla birlikte yazarak güncellemeye çalışmanın farklı bir davranışa yol açacağını unutmayın. Bunun yerine, Grace ve Alan'ı bu şekilde güncellemeye çalışırsak ne olacağına bakalım:

curl -X PATCH -d '{
  "alanisawesome": {"nickname": "Alan The Machine"},
  "gracehopper": {"nickname": "Amazing Grace"}
}' \
  'https://docs-examples.firebaseio.com/fireblog/users.json'

Bu durum, farklı bir davranışa (yani /fireblog/users düğümünün tamamının üzerine yazılmasına) neden olur:

{
  "users": {
    "alanisawesome": {
      "nickname": "Alan The Machine"
    },
    "gracehop": {
      "nickname": "Amazing Grace"
    }
  }
}

Koşullu İsteklerle Verileri Güncelleme

Verileri mevcut durumlarına göre güncellemek için işlemlere eşdeğer olan REST koşullu isteklerini kullanabilirsiniz. Örneğin, olumlu oy sayacını artırmak ve sayacın, aynı anda verilen birden fazla olumlu oyu doğru şekilde yansıttığından emin olmak istiyorsanız yeni değeri sayaca yazmak için koşullu bir istek kullanın. Sayacı aynı sayıya değiştiren iki yazma işlemi yerine, yazma isteklerinden biri başarısız olur ve isteği yeni değerle yeniden deneyebilirsiniz.
  1. Bir konumda koşullu istekte bulunmak için söz konusu konumdaki mevcut verilerin benzersiz tanımlayıcısını veya ETag'i alın. Bu konumdaki veriler değişirse ETag de değişir. PATCH dışındaki herhangi bir yöntemle ETag isteğinde bulunabilirsiniz. Aşağıdaki örnekte GET isteği kullanılmaktadır.
    curl -i 'https://test.example.com/posts/12345/upvotes.json' -H 'X-Firebase-ETag: true'
    Başlıkta ETag'in özellikle çağrılması, HTTP yanıtında belirtilen konumun ETag'ini döndürür.
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    10 // Current value of the data at the specified location
  2. Döndürülen ETag'i, özellikle bu ETag değeriyle eşleşen verileri güncellemek için bir sonraki PUT veya DELETE isteğinize ekleyin. Örneğimizde, sayacı 11'e (ilk getirilen değer olan 10'dan 1 fazla) güncellemek ve değer artık eşleşmiyorsa isteği başarısız kılmak için aşağıdaki kodu kullanın:
    curl -iX PUT -d '11' 'https://[PROJECT_ID].firebaseio.com/posts/12345/upvotes.json' -H 'if-match:[ETAG_VALUE]'
    Belirtilen konumdaki verilerin değeri hâlâ 10 ise PUT isteğindeki ETag eşleşir ve istek başarılı olur. Bu durumda, veritabanına 11 yazılır.
    HTTP/1.1 200 OK
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    Cache-Control: no-cache
    
    11 // New value of the data at the specified location, written by the conditional request
    Başka bir kullanıcı veritabanına yeni bir değer yazarsa konum artık ETag ile eşleşmeyebilir. Bu durumda, konuma yazılmadan istek başarısız olur. Döndürülen yanıtta yeni değer ve ETag bulunur.
    HTTP/1.1 412 Precondition Failed
    Content-Length: 6
    Content-Type: application/json; charset=utf-8
    Access-Control-Allow-Origin: *
    ETag: [ETAG_VALUE]
    Cache-Control: no-cache
    
    12 // New value of the data at the specified location
  3. İsteği yeniden denemeye karar verirseniz yeni bilgileri kullanın. Realtime Database Başarısız olan koşullu istekleri otomatik olarak yeniden denemez. Ancak, hata yanıtı tarafından döndürülen bilgilerle yeni bir koşullu istek oluşturmak için yeni değeri ve ETag'i kullanabilirsiniz.

REST tabanlı koşullu istekler, HTTP if-match standardını uygular. Ancak standarttan şu yönleriyle farklıdırlar:

  • Her if-match isteği için yalnızca bir ETag değeri sağlayabilirsiniz, birden fazla değer sağlayamazsınız.
  • Standart, ETag'lerin tüm isteklerle birlikte döndürülmesini önerse de Realtime Database yalnızca X-Firebase-ETag üstbilgisini içeren isteklerle birlikte ETag döndürür. Bu, standart isteklerin faturalandırma maliyetlerini azaltır.

Koşullu istekler de normal REST isteklerinden daha yavaş olabilir.

Veri Listelerini Kaydetme

Firebase veritabanı referansına eklenen her alt öğe için benzersiz, zaman damgası tabanlı bir anahtar oluşturmak amacıyla POST isteği gönderebiliriz. users yolumuzda, her kullanıcının benzersiz bir kullanıcı adı olduğundan kendi anahtarlarımızı tanımlamak mantıklıydı. Ancak kullanıcılar uygulamaya blog yayınları eklediğinde her blog yayını için otomatik olarak anahtar oluşturmak üzere POST isteği kullanırız:

curl -X POST -d '{
  "author": "alanisawesome",
  "title": "The Turing Machine"
}' 'https://docs-examples.firebaseio.com/fireblog/posts.json'

posts yolumuzda artık şu veriler yer alıyor:

{
  "posts": {
    "-JSOpn9ZC54A4P4RoqVa": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

-JSOpn9ZC54A4P4RoqVa isteği kullandığımız için POST anahtarının bizim için otomatik olarak oluşturulduğunu unutmayın. Başarılı bir istek, 200 OK HTTP durum koduyla belirtilir ve yanıtta eklenen yeni verilerin anahtarı yer alır:

{"name":"-JSOpn9ZC54A4P4RoqVa"}

Verileri Kaldırma

Verileri veritabanından kaldırmak için, verileri silmek istediğimiz yolun URL'siyle birlikte DELETE isteği gönderebiliriz. Aşağıdaki işlem, Alan'ı users yolumuzdan siler:

curl -X DELETE \
  'https://docs-examples.firebaseio.com/fireblog/users/alanisawesome.json'

Başarılı bir DELETE isteği, JSON null içeren bir yanıtla birlikte 200 OK HTTP durum koduyla belirtilir.

URI Parametreleri

REST API, veritabanına veri yazarken aşağıdaki URI parametrelerini kabul eder:

auth

auth istek parametresi, Firebase Realtime Database Security Rules ile korunan verilere erişime izin verir ve tüm istek türleri tarafından desteklenir. Bağımsız değişken, Firebase uygulama gizli anahtarımız veya kullanıcı yetkilendirme bölümünde ele alacağımız bir kimlik doğrulama jetonu olabilir. Aşağıdaki örnekte, POST parametresiyle bir auth isteği gönderiyoruz. Burada CREDENTIAL, Firebase uygulamamızın gizli anahtarı veya bir kimlik doğrulama jetonudur:

curl -X POST -d '{"Authenticated POST request"}' \
  'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'

yazdır

print parametresi, veritabanından gelen yanıtımızın biçimini belirtmemize olanak tanır. İsteğimize print=pretty eklediğimizde veriler, insanlar tarafından okunabilir bir biçimde döndürülür. print=pretty, GET, PUT, POST, PATCH ve DELETE istekleri tarafından desteklenir.

Veri yazarken sunucudan gelen çıkışı bastırmak için isteğimize print=silent ekleyebiliriz. İstek başarılı olursa sonuçta elde edilen yanıt boş olur ve 204 No Content HTTP durum koduyla gösterilir. print=silent, GET, PUT, POST ve PATCH istekleri tarafından desteklenir.

Yazma Sunucusu Değerleri

Sunucu değerleri, tek bir ".sv" anahtarı olan bir nesne olan yer tutucu değeri kullanılarak bir konuma yazılabilir. Bu anahtarın değeri, ayarlamak istediğimiz sunucu değeri türüdür. Örneğin, bir kullanıcı oluşturulduğunda zaman damgası ayarlamak için aşağıdakileri yapabiliriz:

curl -X PUT -d '{".sv": "timestamp"}' \
  'https://docs-examples.firebaseio.com/alanisawesome/createdAt.json'

"timestamp", desteklenen tek sunucu değeridir ve UNIX sıfır zamanından bu yana geçen süreyi milisaniye cinsinden ifade eder.

Yazma Performansını İyileştirme

Veritabanına büyük miktarda veri yazıyorsak yazma performansımızı artırmak ve bant genişliği kullanımını azaltmak için print=silent parametresini kullanabiliriz. Normal yazma davranışında sunucu, yazılan JSON verileriyle yanıt verir. print=silent belirtildiğinde sunucu, veriler alındıktan sonra bağlantıyı hemen kapatarak bant genişliği kullanımını azaltır.

Veritabanına birçok istekte bulunduğumuz durumlarda, HTTP üstbilgisinde bir Keep-Alive isteği göndererek HTTPS bağlantısını yeniden kullanabiliriz.

Hata Koşulları

REST API, aşağıdaki durumlarda hata kodları döndürür:

HTTP Durum Kodları
400 Hatalı İstek

Aşağıdaki hata koşullarından biri:

  • PUT veya POST verileri ayrıştırılamıyor.
  • PUT veya POST verileri eksik.
  • İstek, çok büyük olan verileri PUT veya POST etmeye çalışıyor.
  • REST API çağrısı, yolun bir parçası olarak geçersiz alt adlar içeriyor.
  • REST API çağrı yolu çok uzun.
  • İstek, tanınmayan bir sunucu değeri içeriyor.
  • Sorgunun dizini Firebase Realtime Database Security Rules içinde tanımlanmamış.
  • İstek, belirtilen sorgu parametrelerinden birini desteklemiyor.
  • İstek, sorgu parametrelerini yüzeysel bir GET isteğiyle karıştırıyor.
401 Yetkilendirilmedi (Unauthorized)

Aşağıdaki hata koşullarından biri:

  • Yetkilendirme jetonunun süresi doldu.
  • İstekte kullanılan kimlik doğrulama jetonu geçersiz.
  • access_token ile kimlik doğrulama başarısız oldu.
  • İstek, Firebase Realtime Database Security Rules şartlarınızı ihlal ediyor.
404 Bulunamadı Belirtilen Firebase veritabanı bulunamadı.
500 Dahili Sunucu Hatası Sunucu hata döndürdü. Daha fazla bilgi için hata mesajına bakın.
503 Hizmet Kullanılamıyor Belirtilen Firebase Realtime Database geçici olarak kullanılamıyor. Bu nedenle, istek denenmedi.

Veri güvenliğini sağlama

Firebase'de, verilerimizin farklı düğümlerine hangi kullanıcıların okuma ve yazma erişimine sahip olduğunu tanımlamamıza olanak tanıyan bir güvenlik dili bulunur. Bu konu hakkında daha fazla bilgiye Realtime Database Security Rules adresinden ulaşabilirsiniz.

Verileri kaydetme konusunu ele aldığımıza göre, bir sonraki bölümde verilerimizi Firebase veritabanından REST API aracılığıyla nasıl alacağımızı öğrenebiliriz.