Apple platformlarında Veri Okuma ve Yazma

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

Uygulamanızın Realtime Database ürününden nasıl okuma ve yazma konusundan bahsetmeden önce, Realtime Database prototipini oluşturmak ve bu araçları test etmek için kullanabileceğiniz bir araç setinden bahsedelim. işlev: 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 ürününün 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ü birkaç adımda kullanabilirsiniz:

  1. Emülatöre bağlanmak için uygulamanızın test yapılandırmasına bir kod satırı ekleyin.
  2. Yerel proje dizininizin kök dizininden firebase emulators:start komutunu çalıştırın.
  3. Bir 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 ile ilgili ayrıntılı bir adım adım açıklamalı kılavuz mevcuttur. Local Emulator Suite girişine de göz atmanız önerilir.

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, verilerin ilk durumu için bir kez ve veriler her değiştiğinde tekrar tetiklenir.

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;
  // ...
}];

Dinleyici, value mülkünde etkinlik sırasında veritabanında belirtilen konumdaki verileri içeren bir FIRDataSnapshot alır. 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 veritabanından tek seferde nasıl alınacağı gösterilmektedir:

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, sunucuda güncel bir değer olup olmadığını kontrol etmek yerine yerel önbelleğe ait değerin hemen döndürülmesini isteyebilirsiniz. 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 daha iyi ölçeklendirme için birden fazla konumda depolanıyorsa veri dağıtımını kullanarak bu verilerin tüm örneklerini güncelleyebilirsiniz. Ö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 updateChildValues çağrısıyla JSON ağacını oluşturabilirsiniz (örneğin, bu örnekte 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 ekleme

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 dinleyici, hangi verilerin kaydedildiğini ve hangi verilerin hâlâ senkronize edildiğini takip etmek için yararlı olabilir. Çağrı başarısız olursa dinleyiciye, hatanın nedenini belirten bir hata nesnesi iletilir.

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 kaldırma

Gözlemciler, bir ViewController'den ayrıldığınızda verileri otomatik olarak senkronize etmeyi durdurmaz. 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. Bu konumdaki verilerin senkronizasyonunu durdurmak için removeAllObservers yöntemini çağırarak konumdaki tüm gözlemcileri kaldırmanız gerekir.

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, örnek sosyal blog uygulamasında kullanıcıların yayınlara yıldız eklemesine ve yıldızları kaldırmalarına izin verebilir ve bir yayının kaç yıldız aldığını aşağıdaki gibi takip edebilirsiniz:

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ü, uygulama klipsi 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 daha sonra 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ılır. Bu, uygulamanızın tüm ağ gecikmeleri veya bağlantılarından bağımsız şekilde yanıt verebilir.

Bağlantı yeniden kurulduktan sonra uygulamanız, özel kod yazmak zorunda kalmadan istemcinin mevcut sunucu durumuyla senkronize edilmesi için uygun etkinlik grubunu alır.

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

Sonraki adımlar