Apple platformlarında Veri Okuma ve Yazma

(İsteğe bağlı) Firebase Local Emulator Suite ile prototip oluşturun ve test edin

Uygulamanızın Realtime Database'den nasıl okuduğu ve yazdığından bahsetmeden önce Gerçek Zamanlı Veritabanı'nın prototipini oluşturmak ve test etmek için kullanabileceğiniz bir araç setinden bahsedelim. şu işleve sahip: Firebase Local Emulator Suite. Farklı verileri deniyorsanız güvenlik kurallarınızı optimize ederek veya makine öğreniminden en iyi şekilde arka uçla etkileşim kurmanın ve yerel olarak çalışabilmenin uygun maliyetli bir yoludur. çok iyi bir fikir olabilir.

Realtime Database emülatörü, Local Emulator Suite'in bir parçasıdır. uygulamanızın emüle edilmiş veritabanı içeriğinizle ve yapılandırmanızla etkileşim kurmasına olanak tanır. ve isteğe bağlı olarak emüle edilen proje kaynaklarınızın (işlevler, diğer veritabanları ve güvenlik kuralları) ekleyin.

Realtime Database emülatörünün kullanımı yalnızca birkaç adımdan oluşur:

  1. Emülatöre bağlanmak için uygulamanızın test yapılandırmasına bir kod satırı ekleme.
  2. Yerel proje dizininizin kök dizininden firebase emulators:start komutunu çalıştırın.
  3. Realtime Database platformu kullanarak uygulamanızın prototip kodundan çağrı yapma SDK'yı her zamanki gibi kullanın veya Realtime Database REST API'yi kullanın.

Realtime Database ve Cloud Functions'ı içeren adım adım açıklamalı ayrıntılı bir kılavuz mevcuttur. Ayrıca Local Emulator Suite tanıtımı'na da göz atmalısınız.

FIRDatabaseReference alma

Veritabanından veri okumak veya yazmak için FIRDatabaseReference:

Swift

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
var ref: DatabaseReference!

ref = Database.database().reference()

Objective-C

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];

Verileri yazma

Bu belgede Firebase verilerini okuma ve yazmayla ilgili temel bilgiler verilmektedir.

Firebase verileri bir Database referansına yazılır ve bu referans tarafından alınır. referansa eşzamansız işleyici eklemektir. Dinleyici tetiklenir. bir kez, verilerin ilk durumu için bir kez ve veriler her değiştiğinde bir kez daha düzenleyin.

Temel yazma işlemleri

Temel yazma işlemleri için verileri belirli bir yere kaydetmek üzere setValue kullanabilirsiniz yeni bir referans noktası yaparak bu yoldaki mevcut verilerin yerini alır. Bu yöntemi şu amaçlarla kullanabilirsiniz:

  • Kullanılabilir JSON türlerine karşılık gelen aşağıdaki gibi geçiş türleri:
    • NSString
    • NSNumber
    • NSDictionary
    • NSArray

Örneğin, aşağıdaki gibi setValue içeren bir kullanıcı ekleyebilirsiniz:

Swift

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
self.ref.child("users").child(user.uid).setValue(["username": username])

Objective-C

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
[[[self.ref child:@"users"] child:authResult.user.uid]
    setValue:@{@"username": username}];

setValue bu şekilde kullanılırsa belirtilen konumdaki verilerin üzerine yazılır. dahildir. Ancak, eğer yoksa çocuklarınız için yeniden yazmanız gerekir. Kullanıcıların profillerini güncellemelerine izin vermek istiyorsanız kullanıcı adını şu şekilde güncelleyebilirsiniz:

Swift

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
self.ref.child("users/\(user.uid)/username").setValue(username)

Objective-C

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
[[[[_ref child:@"users"] child:user.uid] child:@"username"] setValue:username];

Verileri okuma

Değer etkinliklerini dinleyerek verileri okuma

Bir yoldaki verileri okumak ve değişiklikleri dinlemek için Gözlemlenecek observeEventType:withBlock / FIRDatabaseReference FIRDataEventTypeValue etkinlik.

Etkinlik türü Tipik kullanım
FIRDataEventTypeValue Bir yolun tüm içeriğindeki değişiklikleri okuma ve dinleme.

Belirli bir yoldaki verileri okumak için FIRDataEventTypeValue etkinliğini kullanabilirsiniz. mevcut hâlini belirler. Bu yöntem, ekli olduğunu görürsünüz. Bunlar, çocuklar da dahil olmak üzere anlamına gelir. Etkinlik geri çağırması, ilgili etkinlikteki tüm verileri içeren bir snapshot iletildi çocuk verileri dahil. Veri yoksa anlık görüntü döndürülür exists() ve nil için value özelliğini okuduğunuzda false.

Aşağıdaki örnekte, ayrıntıları:

Swift

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
refHandle = postRef.observe(DataEventType.value, with: { snapshot in
  // ...
})

Objective-C

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
_refHandle = [_postRef observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
  NSDictionary *postDict = snapshot.value;
  // ...
}];

İşleyici, belirtilenFIRDataSnapshot etkinlik sırasında veritabanında bulunan, value mülkündeki konumu. Siz değerleri NSDictionary gibi uygun yerel türe atayabilir. Konumda veri yoksa value değeri nil olur.

Verileri bir kez oku

getData() kullanarak bir kez okuma

SDK, veritabanı sunucularıyla etkileşimleri yönetecek şekilde tasarlanmıştır. Uygulama çevrimiçi veya çevrimdışı.

Genel olarak, şu bilgileri okumak için yukarıda açıklanan değer etkinlikleri tekniklerini veya arka uçtan veri güncellemelerinin bildirim almasını sağlar. Bu teknikler kullanımınızı ve faturalarınızı azaltır, kullanıcılarınıza en iyi deneyimi sunmak için optimize edilmiştir. hem de çevrimdışı deneyim.

Verilere yalnızca bir kez ihtiyaç duyarsanız, raporun anlık görüntüsünü almak için getData() kullanabilirsiniz bu verileri kaldırmanızı sağlar. getData() herhangi bir nedenle istemci, yerel depolama önbelleğini kontrol eder ve bir hata döndürür. bulabilirsiniz.

Aşağıdaki örnekte, bir kullanıcının herkese açık kullanıcı adının alınması gösterilmektedir tek seferde yalnızca bir kez verilmelidir:

Swift

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
do {
  let snapshot = try await ref.child("users/\(uid)/username").getData()
  let userName = snapshot.value as? String ?? "Unknown"
} catch {
  print(error)
}

Objective-C

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
NSString *userPath = [NSString stringWithFormat:@"users/%@/username", uid];
[[ref child:userPath] getDataWithCompletionBlock:^(NSError * _Nullable error, FIRDataSnapshot * _Nonnull snapshot) {
  if (error) {
    NSLog(@"Received an error %@", error);
    return;
  }
  NSString *userName = snapshot.value;
}];

Gereksiz getData() kullanımı, bant genişliği kullanımını artırabilir ve kayba neden olabilir Bu performans, gösterildiği gibi gerçek zamanlı bir işleyici kullanılarak engellenebilir bölümünü ziyaret edin.

Verileri bir gözlemciyle bir kez okuma

Bazı durumlarda, yerel önbellek değerinin döndürülmesini isteyebilirsiniz güncel bir değer olup olmadığını kontrol etmek yerine anında rapor oluşturur. O observeSingleEventOfType kullanabilir, bu durumlarda yerel disk önbelleğinizi hemen kontrol edin.

Bu, yalnızca bir kez yüklenmesi gereken ve yüklenmesi beklenmeyen veriler için yararlıdır. veya aktif dinlemeyi gerektirir. Örneğin blog uygulaması Yukarıdaki örneklerde, kullanıcı bir web sitesine girdiğinde kullanıcının profilini yüklemek için yeni bir yayın yazmaya başlayın:

Swift

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
let userID = Auth.auth().currentUser?.uid
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { snapshot in
  // Get user value
  let value = snapshot.value as? NSDictionary
  let username = value?["username"] as? String ?? ""
  let user = User(username: username)

  // ...
}) { error in
  print(error.localizedDescription)
}

Objective-C

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
NSString *userID = [FIRAuth auth].currentUser.uid;
[[[_ref child:@"users"] child:userID] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
  // Get user value
  User *user = [[User alloc] initWithUsername:snapshot.value[@"username"]];

  // ...
} withCancelBlock:^(NSError * _Nonnull error) {
  NSLog(@"%@", error.localizedDescription);
}];

Verileri güncelleme veya silme

Belirli alanları güncelle

Diğer düğümlerin üzerine yazmadan bir düğümün belirli alt öğelerine aynı anda yazmak için alt düğümler için updateChildValues yöntemini kullanın.

updateChildValues çağrısı yapılırken alt düzey alt değerleri şu şekilde güncelleyebilirsiniz: anahtar için bir yol belirterek. Veriler ölçeklendirilmek üzere birden fazla konumda depolanıyorsa isterseniz, bu verilerin tüm örneklerini verilerin yayılması. Örneğin, sosyal blog uygulaması bir yayın oluşturup eşzamanlı olarak bunu son etkinlik feed'i ve yayınlayan kullanıcının etkinlik feed'i. Bunu yapmak için blog oluşturma uygulaması şuna benzer bir kod kullanır:

Swift

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
guard let key = ref.child("posts").childByAutoId().key else { return }
let post = ["uid": userID,
            "author": username,
            "title": title,
            "body": body]
let childUpdates = ["/posts/\(key)": post,
                    "/user-posts/\(userID)/\(key)/": post]
ref.updateChildValues(childUpdates)

Objective-C

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
NSString *key = [[_ref child:@"posts"] childByAutoId].key;
NSDictionary *post = @{@"uid": userID,
                       @"author": username,
                       @"title": title,
                       @"body": body};
NSDictionary *childUpdates = @{[@"/posts/" stringByAppendingString:key]: post,
                               [NSString stringWithFormat:@"/user-posts/%@/%@/", userID, key]: post};
[_ref updateChildValues:childUpdates];

Bu örnekte, childByAutoId ile ilgili yayınları içeren düğümde bir yayın oluşturmak için /posts/$postid alanındaki tüm kullanıcıları ve anahtarı getKey(). Bu anahtar, kullanıcının iş sayfasında ikinci bir giriş oluşturmak için kullanılabilir. /user-posts/$userid/$postid itibarıyla yayınları var.

Bu yolları kullanarak, bir bölgedeki birden fazla konumda aynı anda güncelleme yapabilirsiniz. tek bir çağrıyla JSON ağacını (ör. bu örnekte olduğu gibi)updateChildValues yeni yayını her iki konumda da oluşturur. Bu şekilde yapılan eş zamanlı güncellemeler çok önemli: ya tüm güncellemeler başarılı olur ya da tüm güncellemeler başarısız olur.

Tamamlama Bloğu ekle

Verilerinizin ne zaman kaydedildiğini öğrenmek istiyorsanız tamamlama bloğunu ekleyin. Hem setValue hem de updateChildValues isteğe bağlı tamamlama bloğunda olduğu gibi, yazma işlemi Bu işleyici, son 30 güne ait kaydedildiğini ve hangi verilerin senkronize edilmekte olduğunu gösterir. Arama başarısız olduysa işleyiciye hatanın neden oluştuğunu belirten bir hata nesnesi gönderilir.

Swift

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
do {
  try await ref.child("users").child(user.uid).setValue(["username": username])
  print("Data saved successfully!")
} catch {
  print("Data could not be saved: \(error).")
}

Objective-C

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
[[[_ref child:@"users"] child:user.uid] setValue:@{@"username": username} withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
  if (error) {
    NSLog(@"Data could not be saved: %@", error);
  } else {
    NSLog(@"Data saved successfully.");
  }
}];

Verileri silin

Verileri silmenin en basit yolu,removeValue söz konusu verilerin konumu.

Başka bir yazma işleminin değeri olarak nil değerini belirterek de silebilirsiniz setValue veya updateChildValues gibi bir işlem. Bu tekniği kullanarak tek bir API çağrısındaki birden çok alt öğeyi silmek için updateChildValues ile birlikte kullanın.

Dinleyicileri ayır

Bir sunucudan çıktığınızda gözlemciler veri senkronizasyonunu otomatik olarak ViewController Bir gözlemci düzgün şekilde kaldırılmazsa senkronizasyona devam eder. verileri yerel belleğe yükleyin. Artık ihtiyaç duyulmayan gözlemciyi removeObserverWithHandle yöntemiyle ilişkili FIRDatabaseHandle.

Bir referansa geri arama bloğu eklediğinizde FIRDatabaseHandle döndürülür. Bu herkese açık kullanıcı adları, geri çağırma engellemesini kaldırmak için kullanılabilir.

Veritabanı referansına birden fazla işleyici eklenmişse her işleyici bir etkinlik oluşturulduğunda çağrılır. O konumdaki verileri senkronize etmeyi durdurmak için, removeAllObservers işlevini çağırarak bir konumdaki tüm gözlemcileri kaldırmanız gerekir yöntemidir.

Bir dinleyiciden removeObserverWithHandle veya removeAllObservers çağrısı yapıldığında: alt düğümlerine kayıtlı işleyicileri otomatik olarak kaldırmamalıdır; şunları da yapmalısınız: bu referansları veya herkese açık kullanıcı adlarını takip etmeniz gerekir.

Verileri işlem olarak kaydet

Eşzamanlı etkenlere göre bozulabilecek verilerle çalışırken artımlı sayaçlar gibi değişiklikleri yapmak için işlemin işleyiş şekli. Bu işleme bir güncelleme işlevi ve bir isteğe bağlı bağımsız değişken olmak üzere geri arama tamamlanmasını sağlar. Güncelleme işlevi, verilerin mevcut durumunu bağımsız değişken ve yazmak istediğiniz yeni, istenen durumu döndürür.

Örneğin sosyal blog uygulaması örneğimizde, kullanıcıların yayınlara yıldız ekleyebilir, yayınların yıldızlarını kaldırabilir ve ilgili yayının kaç yıldız aldığını takip edebilirsiniz şu şekildedir:

Swift

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
ref.runTransactionBlock({ (currentData: MutableData) -> TransactionResult in
  if var post = currentData.value as? [String: AnyObject],
    let uid = Auth.auth().currentUser?.uid {
    var stars: [String: Bool]
    stars = post["stars"] as? [String: Bool] ?? [:]
    var starCount = post["starCount"] as? Int ?? 0
    if let _ = stars[uid] {
      // Unstar the post and remove self from stars
      starCount -= 1
      stars.removeValue(forKey: uid)
    } else {
      // Star the post and add self to stars
      starCount += 1
      stars[uid] = true
    }
    post["starCount"] = starCount as AnyObject?
    post["stars"] = stars as AnyObject?

    // Set value and report transaction success
    currentData.value = post

    return TransactionResult.success(withValue: currentData)
  }
  return TransactionResult.success(withValue: currentData)
}) { error, committed, snapshot in
  if let error = error {
    print(error.localizedDescription)
  }
}

Objective-C

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
[ref runTransactionBlock:^FIRTransactionResult * _Nonnull(FIRMutableData * _Nonnull currentData) {
  NSMutableDictionary *post = currentData.value;
  if (!post || [post isEqual:[NSNull null]]) {
    return [FIRTransactionResult successWithValue:currentData];
  }

  NSMutableDictionary *stars = post[@"stars"];
  if (!stars) {
    stars = [[NSMutableDictionary alloc] initWithCapacity:1];
  }
  NSString *uid = [FIRAuth auth].currentUser.uid;
  int starCount = [post[@"starCount"] intValue];
  if (stars[uid]) {
    // Unstar the post and remove self from stars
    starCount--;
    [stars removeObjectForKey:uid];
  } else {
    // Star the post and add self to stars
    starCount++;
    stars[uid] = @YES;
  }
  post[@"stars"] = stars;
  post[@"starCount"] = @(starCount);

  // Set value and report transaction success
  currentData.value = post;
  return [FIRTransactionResult successWithValue:currentData];
} andCompletionBlock:^(NSError * _Nullable error,
                       BOOL committed,
                       FIRDataSnapshot * _Nullable snapshot) {
  // Transaction completed
  if (error) {
    NSLog(@"%@", error.localizedDescription);
  }
}];

Bir işlem kullanmak, birden fazla olduğunda yıldız sayısının yanlış olmasını önler kullanıcılar aynı yayına yıldız ekleyebilir veya müşterinin verileri eski olabilir. İlgili içeriği oluşturmak için kullanılan FIRMutableData sınıfında yer alan değer, başlangıçta istemcinin son değeri yol için bilinen değer veya herhangi bir değer yoksa nil. Sunucu, değerin geçerli değerine karşılık gelir ve eşleşmesini veya reddetmesini sağlar. İşlem reddedilirse sunucu değeri daha sonra müşteriye otomatik olarak güncellenmiş değer. Bu işlem, işlem kabul edilene kadar veya çok fazla işlem yapana kadar tekrarlanır deneme yapıldı.

Atomik sunucu tarafı artışları

Yukarıdaki kullanım örneğinde veritabanına iki değer yazıyoruz: Yayına yıldız veren/yıldızı kaldıran kullanıcı ve artan yıldız sayısı. Bir kullanıcının yayına yıldız eklediğini bilirsek atomik bir artış kullanabiliriz işlemidir.

Swift

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
let updates = [
  "posts/\(postID)/stars/\(userID)": true,
  "posts/\(postID)/starCount": ServerValue.increment(1),
  "user-posts/\(postID)/stars/\(userID)": true,
  "user-posts/\(postID)/starCount": ServerValue.increment(1)
] as [String : Any]
Database.database().reference().updateChildValues(updates)

Objective-C

Not: Bu Firebase ürünü, App Clip hedefinde kullanılamaz.
NSDictionary *updates = @{[NSString stringWithFormat: @"posts/%@/stars/%@", postID, userID]: @TRUE,
                        [NSString stringWithFormat: @"posts/%@/starCount", postID]: [FIRServerValue increment:@1],
                        [NSString stringWithFormat: @"user-posts/%@/stars/%@", postID, userID]: @TRUE,
                        [NSString stringWithFormat: @"user-posts/%@/starCount", postID]: [FIRServerValue increment:@1]};
[[[FIRDatabase database] reference] updateChildValues:updates];

Bu kod bir işlem işlemi kullanmadığından otomatik olarak çakışan bir güncelleme varsa yeniden çalıştırın. Ancak, artış işlemi veritabanı sunucusunda gerçekleştiğinden çakışma olasılığı yoktur.

Uygulamaya özel çakışmaları (ör. kullanıcı adı) tespit edip reddetmek istiyorsanız daha önce yıldız eklediğiniz bir yayına yıldız ekleyerek kurallarından bahsedeceğiz.

Verilerle çevrimdışı çalışma

İstemcinin ağ bağlantısı kesilirse uygulamanız çalışmaya devam eder sağlayabilir.

Firebase veritabanına bağlı her istemcinin kendi dahili sürümü bulunur olabilir. Veriler yazıldığında, bu yerel sürüme yazılır. tıklayın. Firebase istemcisi bu verileri uzak veritabanı ile senkronize eder sağlamak için "en iyisini" yaparak .

Sonuç olarak, veritabanına yapılan tüm yazmalar yerel etkinlikleri hemen, sunucuya herhangi bir veri yazıldığından emin olabilirsiniz. Bu, uygulamanızın hızlı bir şekilde yanıt verir.

Bağlantı yeniden kurulduğunda uygulamanız uygun veri kümesini alır Böylece istemcinin, istemcinin bunu gerçekleştirmesine gerek kalmadan mevcut sunucu durumuyla herhangi bir özel kod yazabilirsiniz.

Çevrimdışı davranışlara biraz daha değineceğiz. Online ve çevrimdışı özellikler hakkında daha fazla bilgi edinin.

Sonraki adımlar