(İ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:
- Emülatöre bağlanmak için uygulamanızın test yapılandırmasına bir kod satırı ekleyin.
- Yerel proje dizininizin kök dizininden
firebase emulators:start
komutunu çalıştırın. - 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
var ref: DatabaseReference! ref = Database.database().reference()
Objective-C
@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
self.ref.child("users").child(user.uid).setValue(["username": username])
Objective-C
[[[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
self.ref.child("users/\(user.uid)/username").setValue(username)
Objective-C
[[[[_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
refHandle = postRef.observe(DataEventType.value, with: { snapshot in // ... })
Objective-C
_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
do { let snapshot = try await ref.child("users/\(uid)/username").getData() let userName = snapshot.value as? String ?? "Unknown" } catch { print(error) }
Objective-C
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
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
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
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
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
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
[[[_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
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
[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
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
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.