(İsteğe bağlı) Firebase Local Emulator Suite ile prototip oluşturun ve test edin
Uygulamanızın Realtime Database'den okuma ve yazma işlemleri hakkında konuşmadan önce, Realtime Database işlevselliğini prototiplemek ve test etmek için kullanabileceğiniz bir dizi aracı tanıtalım: Firebase Local Emulator Suite. Farklı veri modelleri deniyor, güvenlik kurallarınızı optimize ediyor veya arka uçla etkileşim kurmanın en uygun maliyetli yolunu bulmaya çalışıyorsanız, canlı hizmetleri dağıtmadan yerel olarak çalışabilmek harika bir fikir olabilir.
Gerçek Zamanlı Veritabanı öykünücüsü, uygulamanızın öykünülmüş veritabanı içeriğiniz ve yapılandırmanızın yanı sıra isteğe bağlı olarak öykünmüş proje kaynaklarınızla (işlevler, diğer veritabanları ve güvenlik kuralları) etkileşime girmesini sağlayan Yerel Öykünücü Paketinin bir parçasıdır.
Gerçek Zamanlı Veritabanı öykünücüsünü kullanmak yalnızca birkaç adımı içerir:
- Öykünücüye bağlanmak için uygulamanızın test yapılandırmasına bir kod satırı ekleme.
- Yerel proje dizininizin kökünden, çalıştırılan
firebase emulators:start
. - Her zamanki gibi bir Realtime Database platformu SDK'sı veya Realtime Database REST API kullanarak uygulamanızın prototip kodundan çağrı yapma.
Gerçek Zamanlı Veritabanı ve Bulut İşlevlerini içeren ayrıntılı bir kılavuz mevcuttur. Local Emulator Suite tanıtımına da bir göz atmalısınız.
Bir veritabanı referansı alın
Veritabanından veri okumak veya yazmak için bir firebase.database.Reference
örneğine ihtiyacınız vardır:
Web modular API
import { getDatabase } from "firebase/database"; const database = getDatabase();
Web namespaced API
var database = firebase.database();
Veri yaz
Bu belge, veri almanın temellerini ve Firebase verilerinin nasıl sıralanıp filtreleneceğini kapsar.
Firebase verileri, bir firebase.database.Reference
öğesine eşzamansız bir dinleyici eklenerek alınır. Dinleyici, verilerin ilk durumu için bir kez ve veriler değiştiğinde tekrar tetiklenir.
Temel yazma işlemleri
Temel yazma işlemleri için, verileri belirtilen bir referansa kaydetmek ve bu yoldaki mevcut verileri değiştirmek için set()
kullanabilirsiniz. Örneğin, bir sosyal blog uygulaması set()
ile bir kullanıcıyı aşağıdaki gibi ekleyebilir:
Web modular API
import { getDatabase, ref, set } from "firebase/database"; function writeUserData(userId, name, email, imageUrl) { const db = getDatabase(); set(ref(db, 'users/' + userId), { username: name, email: email, profile_picture : imageUrl }); }
Web namespaced API
function writeUserData(userId, name, email, imageUrl) { firebase.database().ref('users/' + userId).set({ username: name, email: email, profile_picture : imageUrl }); }
set()
kullanılması, alt düğümler de dahil olmak üzere belirtilen konumdaki verilerin üzerine yazar.
Verileri oku
Değer olaylarını dinle
Bir yoldaki verileri okumak ve değişiklikleri dinlemek için olayları gözlemlemek üzere onValue()
kullanın. Belirli bir yoldaki içeriklerin statik anlık görüntülerini, olay sırasında var oldukları şekliyle okumak için bu olayı kullanabilirsiniz. Bu yöntem, dinleyici eklendiğinde bir kez ve çocuklar da dahil olmak üzere veriler her değiştiğinde tekrar tetiklenir. Olay geri araması, alt veriler de dahil olmak üzere o konumdaki tüm verileri içeren bir anlık görüntü iletilir. Herhangi bir veri yoksa, snapshot, üzerine exists()
çağırdığınızda false
, val()
öğesini çağırdığınızda ise null
değerini döndürür.
Aşağıdaki örnek, bir gönderinin yıldız sayısını veritabanından alan bir sosyal blog uygulamasını göstermektedir:
Web modular API
import { getDatabase, ref, onValue} from "firebase/database"; const db = getDatabase(); const starCountRef = ref(db, 'posts/' + postId + '/starCount'); onValue(starCountRef, (snapshot) => { const data = snapshot.val(); updateStarCount(postElement, data); });
Web namespaced API
var starCountRef = firebase.database().ref('posts/' + postId + '/starCount'); starCountRef.on('value', (snapshot) => { const data = snapshot.val(); updateStarCount(postElement, data); });
Dinleyici, olay anında veritabanında belirtilen konumdaki verileri içeren bir snapshot
alır. snapshot
görüntüdeki verileri val()
yöntemiyle alabilirsiniz.
Verileri bir kez oku
get() ile verileri bir kez oku
SDK, uygulamanız ister çevrimiçi ister çevrimdışı olsun, veritabanı sunucularıyla etkileşimleri yönetmek için tasarlanmıştır.
Genel olarak, arka uçtan veri güncellemelerinden haberdar olmak için verileri okumak üzere yukarıda açıklanan değer olay tekniklerini kullanmalısınız. Dinleyici teknikleri, kullanımınızı ve faturalandırmanızı azaltır ve kullanıcılarınıza çevrimiçi ve çevrimdışı olduklarında en iyi deneyimi sunmak için optimize edilmiştir.
Verilere yalnızca bir kez ihtiyacınız varsa, veritabanından verilerin anlık görüntüsünü almak için get()
kullanabilirsiniz. Herhangi bir nedenle get()
sunucu değerini döndüremezse, müşteri yerel depolama önbelleğini inceler ve değer hala bulunamazsa bir hata döndürür.
Gereksiz get()
kullanımı, bant genişliği kullanımını artırabilir ve yukarıda gösterildiği gibi gerçek zamanlı bir dinleyici kullanılarak önlenebilecek performans kaybına neden olabilir.
Web modular API
import { getDatabase, ref, child, get } from "firebase/database"; const dbRef = ref(getDatabase()); get(child(dbRef, `users/${userId}`)).then((snapshot) => { if (snapshot.exists()) { console.log(snapshot.val()); } else { console.log("No data available"); } }).catch((error) => { console.error(error); });
Web namespaced API
const dbRef = firebase.database().ref(); dbRef.child("users").child(userId).get().then((snapshot) => { if (snapshot.exists()) { console.log(snapshot.val()); } else { console.log("No data available"); } }).catch((error) => { console.error(error); });
Bir gözlemci ile verileri bir kez okuyun
Bazı durumlarda, sunucuda güncellenmiş bir değer olup olmadığını kontrol etmek yerine, yerel önbellekten gelen değerin hemen döndürülmesini isteyebilirsiniz. Bu durumlarda, verileri yerel disk önbelleğinden hemen almak için once()
öğesini kullanabilirsiniz.
Bu, yalnızca bir kez yüklenmesi gereken ve sık sık değişmesi veya aktif dinleme gerektirmesi beklenmeyen veriler için kullanışlıdır. Örneğin, önceki örneklerde yer alan blog uygulaması, yeni bir gönderi yazmaya başladıklarında bir kullanıcının profilini yüklemek için bu yöntemi kullanır:
Web modular API
import { getDatabase, ref, onValue } from "firebase/database"; import { getAuth } from "firebase/auth"; const db = getDatabase(); const auth = getAuth(); const userId = auth.currentUser.uid; return onValue(ref(db, '/users/' + userId), (snapshot) => { const username = (snapshot.val() && snapshot.val().username) || 'Anonymous'; // ... }, { onlyOnce: true });
Web namespaced API
var userId = firebase.auth().currentUser.uid; return firebase.database().ref('/users/' + userId).once('value').then((snapshot) => { var username = (snapshot.val() && snapshot.val().username) || 'Anonymous'; // ... });
Verileri güncelleme veya silme
Belirli alanları güncelle
Diğer alt düğümlerin üzerine yazmadan aynı anda bir düğümün belirli alt öğelerine yazmak için update()
yöntemini kullanın.
update()
öğesini çağırırken, anahtar için bir yol belirterek alt düzey alt değerleri güncelleyebilirsiniz. Veriler daha iyi ölçeklendirmek için birden çok konumda depolanıyorsa, veri yayma özelliğini kullanarak bu verilerin tüm örneklerini güncelleyebilirsiniz.
Örneğin, bir sosyal blog uygulaması, aşağıdaki gibi bir kod kullanarak bir gönderi oluşturabilir ve aynı anda bunu en son etkinlik akışına ve gönderen kullanıcının etkinlik akışına güncelleyebilir:
Web modular API
import { getDatabase, ref, child, push, update } from "firebase/database"; function writeNewPost(uid, username, picture, title, body) { const db = getDatabase(); // A post entry. const postData = { author: username, uid: uid, body: body, title: title, starCount: 0, authorPic: picture }; // Get a key for a new Post. const newPostKey = push(child(ref(db), 'posts')).key; // Write the new post's data simultaneously in the posts list and the user's post list. const updates = {}; updates['/posts/' + newPostKey] = postData; updates['/user-posts/' + uid + '/' + newPostKey] = postData; return update(ref(db), updates); }
Web namespaced API
function writeNewPost(uid, username, picture, title, body) { // A post entry. var postData = { author: username, uid: uid, body: body, title: title, starCount: 0, authorPic: picture }; // Get a key for a new Post. var newPostKey = firebase.database().ref().child('posts').push().key; // Write the new post's data simultaneously in the posts list and the user's post list. var updates = {}; updates['/posts/' + newPostKey] = postData; updates['/user-posts/' + uid + '/' + newPostKey] = postData; return firebase.database().ref().update(updates); }
Bu örnek, düğümde /posts/$postid
tüm kullanıcılar için gönderiler içeren bir gönderi oluşturmak ve aynı anda anahtarı almak için push()
u kullanır. Anahtar daha sonra kullanıcının /user-posts/$userid/$postid
adresindeki gönderilerinde ikinci bir giriş oluşturmak için kullanılabilir.
Bu yolları kullanarak, tek bir update()
çağrısıyla JSON ağacındaki birden fazla konumda eşzamanlı güncellemeler gerçekleştirebilirsiniz, örneğin bu örneğin her iki konumda da yeni gönderiyi nasıl oluşturduğu gibi. Bu şekilde yapılan eşzamanlı güncellemeler atomiktir: ya tüm güncellemeler başarılı olur ya da tüm güncellemeler başarısız olur.
Bir Tamamlama Geri Araması Ekleyin
Verilerinizin ne zaman işlendiğini bilmek istiyorsanız, bir tamamlama geri araması ekleyebilirsiniz. Hem set()
hem de update()
yazma veritabanına işlendiğinde çağrılan isteğe bağlı bir tamamlama geri araması alır. Arama başarısız olursa, geri arama, hatanın neden oluştuğunu gösteren bir hata nesnesi iletilir.
Web modular API
import { getDatabase, ref, set } from "firebase/database"; const db = getDatabase(); set(ref(db, 'users/' + userId), { username: name, email: email, profile_picture : imageUrl }) .then(() => { // Data saved successfully! }) .catch((error) => { // The write failed... });
Web namespaced API
firebase.database().ref('users/' + userId).set({ username: name, email: email, profile_picture : imageUrl }, (error) => { if (error) { // The write failed... } else { // Data saved successfully! } });
Verileri sil
Verileri silmenin en basit yolu, o verinin konumuna referansla remove()
işlevini çağırmaktır.
set()
veya update()
gibi başka bir yazma işlemi için değer olarak null
belirterek de silebilirsiniz. Tek bir API çağrısında birden çok alt öğeyi silmek için bu tekniği update()
ile kullanabilirsiniz.
Bir Promise
Almak
Verilerinizin Firebase Gerçek Zamanlı Veritabanı sunucusuna ne zaman kaydedildiğini bilmek için bir Promise
kullanabilirsiniz. Hem set()
hem de update()
yazmanın veritabanına ne zaman kaydedildiğini bilmek için kullanabileceğiniz bir Promise
döndürebilir.
Dinleyicileri ayırın
Geri aramalar, Firebase veritabanı referansınızdaki off()
yöntemi çağrılarak kaldırılır.
Tek bir dinleyiciyi off()
işlevine parametre olarak ileterek kaldırabilirsiniz. Argümansız konumda off()
çağrılması, o konumdaki tüm dinleyicileri kaldırır.
Bir üst dinleyicide off()
çağrısı yapmak, alt düğümlerinde kayıtlı dinleyicileri otomatik olarak kaldırmaz; off()
ayrıca geri aramayı kaldırmak için tüm alt dinleyicilerde çağrılmalıdır.
Verileri işlem olarak kaydet
Artımlı sayaçlar gibi eşzamanlı değişikliklerle bozulabilecek verilerle çalışırken bir işlem işlemi kullanabilirsiniz. Bu işleme bir güncelleme işlevi ve isteğe bağlı bir tamamlama geri araması verebilirsiniz. Güncelleme işlevi, verilerin mevcut durumunu bir argüman olarak alır ve yazmak istediğiniz yeni istenen durumu döndürür. Yeni değeriniz başarıyla yazılmadan önce başka bir istemci konuma yazarsa, güncelleme işleviniz yeni geçerli değerle tekrar çağrılır ve yazma yeniden denenir.
Örneğin, örnek sosyal blog uygulamasında, kullanıcıların gönderilere yıldız eklemesine ve yıldızları kaldırmasına izin verebilir ve aşağıdaki gibi bir gönderinin kaç yıldız aldığını takip edebilirsiniz:
Web modular API
import { getDatabase, ref, runTransaction } from "firebase/database"; function toggleStar(uid) { const db = getDatabase(); const postRef = ref(db, '/posts/foo-bar-123'); runTransaction(postRef, (post) => { if (post) { if (post.stars && post.stars[uid]) { post.starCount--; post.stars[uid] = null; } else { post.starCount++; if (!post.stars) { post.stars = {}; } post.stars[uid] = true; } } return post; }); }
Web namespaced API
function toggleStar(postRef, uid) { postRef.transaction((post) => { if (post) { if (post.stars && post.stars[uid]) { post.starCount--; post.stars[uid] = null; } else { post.starCount++; if (!post.stars) { post.stars = {}; } post.stars[uid] = true; } } return post; }); }
Bir işlemin kullanılması, birden fazla kullanıcının aynı gönderiye aynı anda yıldız vermesi veya müşterinin eski verileri olması durumunda yıldız sayımlarının yanlış olmasını önler. İşlem reddedilirse sunucu, işlemi güncellenen değerle yeniden çalıştıran istemciye geçerli değeri döndürür. Bu, işlem kabul edilene veya siz işlemi iptal edene kadar tekrarlanır.
Atomik sunucu tarafı artışları
Yukarıdaki kullanım durumunda, veritabanına iki değer yazıyoruz: gönderiye yıldız koyan/yıldızı kaldıran kullanıcının kimliği ve artan yıldız sayısı. Bu kullanıcının gönderiyi paylaştığını zaten biliyorsak, işlem yerine atomik bir artış işlemi kullanabiliriz.
Web modular API
function addStar(uid, key) { import { getDatabase, increment, ref, update } from "firebase/database"; const dbRef = ref(getDatabase()); const updates = {}; updates[`posts/${key}/stars/${uid}`] = true; updates[`posts/${key}/starCount`] = increment(1); updates[`user-posts/${key}/stars/${uid}`] = true; updates[`user-posts/${key}/starCount`] = increment(1); update(dbRef, updates); }
Web namespaced API
function addStar(uid, key) { const updates = {}; updates[`posts/${key}/stars/${uid}`] = true; updates[`posts/${key}/starCount`] = firebase.database.ServerValue.increment(1); updates[`user-posts/${key}/stars/${uid}`] = true; updates[`user-posts/${key}/starCount`] = firebase.database.ServerValue.increment(1); firebase.database().ref().update(updates); }
Bu kod bir işlem işlemi kullanmaz, bu nedenle çakışan bir güncelleme varsa otomatik olarak yeniden çalıştırılmaz. Ancak artırma işlemi doğrudan veritabanı sunucusunda gerçekleştiği için çakışma ihtimali yoktur.
Bir kullanıcının daha önce yıldız verdiği bir gönderiye yıldız eklemesi gibi uygulamaya özgü çakışmaları algılamak ve reddetmek istiyorsanız, bu kullanım durumu için özel güvenlik kuralları yazmalısınız.
Verilerle çevrimdışı çalışın
Bir istemci ağ bağlantısını kaybederse uygulamanız düzgün çalışmaya devam eder.
Bir Firebase veritabanına bağlı her istemci, tüm etkin verilerin kendi dahili sürümünü korur. Veri yazıldığında, önce bu yerel sürüme yazılır. Firebase istemcisi daha sonra bu verileri uzak veritabanı sunucularıyla ve diğer istemcilerle "en iyi çaba" esasına göre senkronize eder.
Sonuç olarak, veritabanına yapılan tüm yazma işlemleri, herhangi bir veri sunucuya yazılmadan hemen önce yerel olayları tetikler. Bu, uygulamanızın ağ gecikmesinden veya bağlantıdan bağımsız olarak yanıt vermeye devam ettiği anlamına gelir.
Bağlantı yeniden sağlandıktan sonra uygulamanız, herhangi bir özel kod yazmak zorunda kalmadan istemcinin geçerli sunucu durumuyla eşitlenmesi için uygun olay kümesini alır.
Çevrimiçi ve çevrimdışı yetenekler hakkında daha fazla bilgi edinin bölümünde çevrimdışı davranış hakkında daha fazla konuşacağız.