Verileri Kaydetme

Bu belgede, Firebase Realtime Database'inize veri yazmak için kullanabileceğiniz dört yöntem ele alınmaktadır: set, güncelleme, aktarma ve işlem desteği.

Veri Kaydetme Yöntemleri

set Verileri messages/users/<username> gibi tanımlı bir yola yazın veya değiştirin
update Tüm verileri değiştirmeden, tanımlanmış bir yolun bazı anahtarlarını güncelleme
push Veritabanındaki veri listesine ekleme. Bir listeye her yeni düğüm aktarışınızda veritabanınız messages/users/<unique-user-id>/<username> gibi benzersiz bir anahtar oluşturur
işlem Eşzamanlı güncellemelerle bozulabilecek karmaşık verilerle çalışırken işlemleri kullanın.

Verileri Kaydetme

Temel veritabanı yazma işlemi, yeni verileri belirtilen veritabanı referansına kaydederek ilgili yoldaki mevcut tüm verilerin yerine geçen bir kümedir. Kümeyi anlamak için basit bir blog uygulamasıdır. Uygulamanızın verileri şu veritabanı referansında depolanır:

Java
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("server/saving-data/fireblog");
Node.js
// Import Admin SDK
const { getDatabase } = require('firebase-admin/database');

// Get a database reference to our blog
const db = getDatabase();
const ref = db.ref('server/saving-data/fireblog');
Python
# Import database module.
from firebase_admin import db

# Get a database reference to our blog.
ref = db.reference('server/saving-data/fireblog')
Go
// Create a database client from App.
client, err := app.Database(ctx)
if err != nil {
	log.Fatalln("Error initializing database client:", err)
}

// Get a database reference to our blog.
ref := client.NewRef("server/saving-data/fireblog")

Kullanıcı verilerini kaydederek başlayalım. Her kullanıcıyı benzersiz bir kullanıcı adıyla kaydederiz, ayrıca kullanıcının tam adı ile doğum tarihini de kaydederiz. Her kullanıcının benzersiz bir kullanıcı adı olduğu için, Anahtara zaten sahip olduğunuz ve bunu oluşturmanız gerekmediği için push yöntemi yerine burada ayarla yöntemini kullanmak daha mantıklıdır.

Öncelikle kullanıcı verileriniz için bir veritabanı referansı oluşturun. Ardından kullanıcının kullanıcı adı, tam adı ve doğum günü ile veritabanına bir kullanıcı nesnesi kaydetmek için set() / setValue() öğelerini kullanın. Küme, sayı, boole, null, dizi veya herhangi bir JSON nesnesini iletebilirsiniz. null geçildiğinde, belirtilen konumdaki veriler kaldırılır. Bu durumda, ona bir nesne iletirsiniz:

Java
public static class User {

  public String date_of_birth;
  public String full_name;
  public String nickname;

  public User(String dateOfBirth, String fullName) {
    // ...
  }

  public User(String dateOfBirth, String fullName, String nickname) {
    // ...
  }

}

DatabaseReference usersRef = ref.child("users");

Map<String, User> users = new HashMap<>();
users.put("alanisawesome", new User("June 23, 1912", "Alan Turing"));
users.put("gracehop", new User("December 9, 1906", "Grace Hopper"));

usersRef.setValueAsync(users);
Node.js
const usersRef = ref.child('users');
usersRef.set({
  alanisawesome: {
    date_of_birth: 'June 23, 1912',
    full_name: 'Alan Turing'
  },
  gracehop: {
    date_of_birth: 'December 9, 1906',
    full_name: 'Grace Hopper'
  }
});
Python
users_ref = ref.child('users')
users_ref.set({
    'alanisawesome': {
        'date_of_birth': 'June 23, 1912',
        'full_name': 'Alan Turing'
    },
    'gracehop': {
        'date_of_birth': 'December 9, 1906',
        'full_name': 'Grace Hopper'
    }
})
Go

// User is a json-serializable type.
type User struct {
	DateOfBirth string `json:"date_of_birth,omitempty"`
	FullName    string `json:"full_name,omitempty"`
	Nickname    string `json:"nickname,omitempty"`
}

usersRef := ref.Child("users")
err := usersRef.Set(ctx, map[string]*User{
	"alanisawesome": {
		DateOfBirth: "June 23, 1912",
		FullName:    "Alan Turing",
	},
	"gracehop": {
		DateOfBirth: "December 9, 1906",
		FullName:    "Grace Hopper",
	},
})
if err != nil {
	log.Fatalln("Error setting value:", err)
}

Veritabanına bir JSON nesnesi kaydedildiğinde, nesne özellikleri otomatik olarak veritabanı alt öğesine eşlenir şekilde konumlandırabilir. Şimdi https://docs-examples.firebaseio.com/server/saving-data/fireblog/users/alanisawesome/full_name URL'sine gittiğinizde, "Alan Turing" değerini göreceğiz. Verileri doğrudan çocuğun konumuna da kaydedebilirsiniz:

Java
usersRef.child("alanisawesome").setValueAsync(new User("June 23, 1912", "Alan Turing"));
usersRef.child("gracehop").setValueAsync(new User("December 9, 1906", "Grace Hopper"));
Node.js
const usersRef = ref.child('users');
usersRef.child('alanisawesome').set({
  date_of_birth: 'June 23, 1912',
  full_name: 'Alan Turing'
});
usersRef.child('gracehop').set({
  date_of_birth: 'December 9, 1906',
  full_name: 'Grace Hopper'
});
Python
users_ref.child('alanisawesome').set({
    'date_of_birth': 'June 23, 1912',
    'full_name': 'Alan Turing'
})
users_ref.child('gracehop').set({
    'date_of_birth': 'December 9, 1906',
    'full_name': 'Grace Hopper'
})
Go
if err := usersRef.Child("alanisawesome").Set(ctx, &User{
	DateOfBirth: "June 23, 1912",
	FullName:    "Alan Turing",
}); err != nil {
	log.Fatalln("Error setting value:", err)
}

if err := usersRef.Child("gracehop").Set(ctx, &User{
	DateOfBirth: "December 9, 1906",
	FullName:    "Grace Hopper",
}); err != nil {
	log.Fatalln("Error setting value:", err)
}

Yukarıdaki iki örnekte her iki değerin de bir nesne olarak aynı anda yazılması ve bunları alt konumlara ayrı ayrı yazılması, aynı verilerin veritabanınıza kaydedilmesiyle sonuçlanır:

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

İlk örnek, verileri izleyen müşteriler için yalnızca bir etkinliği tetikler. İkinci örnek, , iki öğeyi tetikleyecektir. usersRef web sitesindeki veriler zaten mevcutsa ilk yaklaşımın bunun üzerine yazar, ancak ikinci yöntem ayrılırken yalnızca her bir ayrı alt düğümün değerini değiştirir usersRef öğesinin diğer alt öğeleri değişmedi.

Kaydedilen Verileri Güncelleme

Diğer kullanıcıların üzerine yazmadan, bir veritabanı konumunun birden çok alt öğesine aynı anda yazmak istiyorsanız alt düğümleri varsa aşağıda gösterilen güncelleme yöntemini kullanabilirsiniz:

Java
DatabaseReference hopperRef = usersRef.child("gracehop");
Map<String, Object> hopperUpdates = new HashMap<>();
hopperUpdates.put("nickname", "Amazing Grace");

hopperRef.updateChildrenAsync(hopperUpdates);
Node.js
const usersRef = ref.child('users');
const hopperRef = usersRef.child('gracehop');
hopperRef.update({
  'nickname': 'Amazing Grace'
});
Python
hopper_ref = users_ref.child('gracehop')
hopper_ref.update({
    'nickname': 'Amazing Grace'
})
Go
hopperRef := usersRef.Child("gracehop")
if err := hopperRef.Update(ctx, map[string]interface{}{
	"nickname": "Amazing Grace",
}); err != nil {
	log.Fatalln("Error updating child:", err)
}

Bu işlem, Gözde'nin verilerini, takma adını içerecek şekilde günceller. Güncelleme yerine burada ayarlamış olsaydınız hopperRef cihazınızdan hem full_name hem de date_of_birth silinecekti.

Firebase Realtime Database, çok yollu güncellemeleri de destekler. Bu, güncelleme işleminin artık güncellenebileceği anlamına gelir. veri tabanınızdaki birden fazla konumdaki değerlere aynı anda ulaşmanızı sağlayan güçlü bir özelliktir. denizasyon oranınızı verilerinizi kontrol edin. Çok yollu güncellemeleri kullanarak hem Gözde hem de Ahmet'e aynı anda takma ad ekleyebilirsiniz zaman:

Java
Map<String, Object> userUpdates = new HashMap<>();
userUpdates.put("alanisawesome/nickname", "Alan The Machine");
userUpdates.put("gracehop/nickname", "Amazing Grace");

usersRef.updateChildrenAsync(userUpdates);
Node.js
const usersRef = ref.child('users');
usersRef.update({
  'alanisawesome/nickname': 'Alan The Machine',
  'gracehop/nickname': 'Amazing Grace'
});
Python
users_ref.update({
    'alanisawesome/nickname': 'Alan The Machine',
    'gracehop/nickname': 'Amazing Grace'
})
Go
if err := usersRef.Update(ctx, map[string]interface{}{
	"alanisawesome/nickname": "Alan The Machine",
	"gracehop/nickname":      "Amazing Grace",
}); err != nil {
	log.Fatalln("Error updating children:", err)
}

Bu güncellemeden sonra hem Ahmet hem de Gözde'nin 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"
    }
  }
}

Yolları içeren nesneleri yazarak nesneleri güncellemeye çalışmanın farklı davranışlara yol açacağını unutmayın. Şimdi Gözde ve Ahmet'i şu şekilde güncellemeye çalışırsanız neler olacağına bakalım:

Java
Map<String, Object> userNicknameUpdates = new HashMap<>();
userNicknameUpdates.put("alanisawesome", new User(null, null, "Alan The Machine"));
userNicknameUpdates.put("gracehop", new User(null, null, "Amazing Grace"));

usersRef.updateChildrenAsync(userNicknameUpdates);
Node.js
const usersRef = ref.child('users');
usersRef.update({
  'alanisawesome': {
    'nickname': 'Alan The Machine'
  },
  'gracehop': {
    'nickname': 'Amazing Grace'
  }
});
Python
users_ref.update({
    'alanisawesome': {
        'nickname': 'Alan The Machine'
    },
    'gracehop': {
        'nickname': 'Amazing Grace'
    }
})
Go
if err := usersRef.Update(ctx, map[string]interface{}{
	"alanisawesome": &User{Nickname: "Alan The Machine"},
	"gracehop":      &User{Nickname: "Amazing Grace"},
}); err != nil {
	log.Fatalln("Error updating children:", err)
}

Bu, farklı bir davranışa neden olur ve /users düğümünün tamamının üzerine yazılır.

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

Tamamlama Geri Çağırması Ekleme

Node.js ve Java Yönetici SDK'larında verilerinizin ne zaman kaydedildiğini öğrenmek istiyorsanız tamamlanan geri çağırma ekleyebilirsiniz. Bu SDK'lardaki hem set hem de güncelleme yöntemleri isteğe bağlı olarak bir tamamlama geri çağırması alır. . Bazı kullanıcılar için arama başarısız olduysa geri çağırma, hatanın neden oluştuğunu belirten bir hata nesnesi iletilir. Python ve Go Admin SDK'larında tüm yazma yöntemleri engellemektedir. Yani yazma yöntemleri, bu süre içinde işlem yapacaksınız.

Java
DatabaseReference dataRef = ref.child("data");
dataRef.setValue("I'm writing data", new DatabaseReference.CompletionListener() {
  @Override
  public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
    if (databaseError != null) {
      System.out.println("Data could not be saved " + databaseError.getMessage());
    } else {
      System.out.println("Data saved successfully.");
    }
  }
});
Node.js
dataRef.set('I\'m writing data', (error) => {
  if (error) {
    console.log('Data could not be saved.' + error);
  } else {
    console.log('Data saved successfully.');
  }
});

Veri Listelerini Kaydetme

Veri listeleri oluştururken çoğu uygulamanın ve her bir uygulamanın çok kullanıcılı yapısını dikkate almak liste yapınızı buna göre ayarlayın. Yukarıdaki örneğe dönecek olursak, uygulamanıza blog yayınları ekleyelim. Sizin ilk içgüdü, şu:

// NOT RECOMMENDED - use push() instead!
{
  "posts": {
    "0": {
      "author": "gracehop",
      "title": "Announcing COBOL, a New Programming Language"
    },
    "1": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

Kullanıcının eklediği yeni yayınlar /posts/2 olarak depolanır. Yalnızca tek bir yazar olsaydı önceden yayın ekliyordu ancak ortak çalışmaya dayalı blog oluşturma uygulamanızda aynı anda birçok kullanıcı yayın ekleyebilir. Eğer İki yazar aynı anda /posts/2 ürününe yazarsa yayınlardan biri diğeri tarafından silinir.

Bu sorunu çözmek için Firebase istemcileri, push() Her yeni alt öğe için benzersiz anahtar. Benzersiz alt anahtarlar sayesinde birçok müşteri yazma çakışmalarını düşünmeden aynı anda aynı konuma alt öğeleri ekleyebilir.

Java
public static class Post {

  public String author;
  public String title;

  public Post(String author, String title) {
    // ...
  }

}

DatabaseReference postsRef = ref.child("posts");

DatabaseReference newPostRef = postsRef.push();
newPostRef.setValueAsync(new Post("gracehop", "Announcing COBOL, a New Programming Language"));

// We can also chain the two calls together
postsRef.push().setValueAsync(new Post("alanisawesome", "The Turing Machine"));
Node.js
const newPostRef = postsRef.push();
newPostRef.set({
  author: 'gracehop',
  title: 'Announcing COBOL, a New Programming Language'
});

// we can also chain the two calls together
postsRef.push().set({
  author: 'alanisawesome',
  title: 'The Turing Machine'
});
Python
posts_ref = ref.child('posts')

new_post_ref = posts_ref.push()
new_post_ref.set({
    'author': 'gracehop',
    'title': 'Announcing COBOL, a New Programming Language'
})

# We can also chain the two calls together
posts_ref.push().set({
    'author': 'alanisawesome',
    'title': 'The Turing Machine'
})
Go

// Post is a json-serializable type.
type Post struct {
	Author string `json:"author,omitempty"`
	Title  string `json:"title,omitempty"`
}

postsRef := ref.Child("posts")

newPostRef, err := postsRef.Push(ctx, nil)
if err != nil {
	log.Fatalln("Error pushing child node:", err)
}

if err := newPostRef.Set(ctx, &Post{
	Author: "gracehop",
	Title:  "Announcing COBOL, a New Programming Language",
}); err != nil {
	log.Fatalln("Error setting value:", err)
}

// We can also chain the two calls together
if _, err := postsRef.Push(ctx, &Post{
	Author: "alanisawesome",
	Title:  "The Turing Machine",
}); err != nil {
	log.Fatalln("Error pushing child node:", err)
}

Benzersiz anahtar, bir zaman damgasına dayalı olduğundan liste öğeleri otomatik olarak kronolojik olarak sıralanır. Firebase her blog yayını için benzersiz bir anahtar oluşturduğundan, birden fazla kullanıcı olması durumunda yazma çakışması olmaz aynı anda yayın ekleyebilir. Veritabanı verileriniz artık aşağıdaki gibi görünür:

{
  "posts": {
    "-JRHTHaIs-jNPLXOQivY": {
      "author": "gracehop",
      "title": "Announcing COBOL, a New Programming Language"
    },
    "-JRHTHaKuITFIhnj02kE": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

JavaScript, Python ve Go'da, push() ve ardından hemen set() çağrısı yapma kalıbı Firebase SDK'sı, ayarlanacak verileri doğrudan push() öğesine aşağıdaki şekilde ileterek bunları birleştirmenize olanak tanır.

Java
// No Java equivalent
Node.js
// This is equivalent to the calls to push().set(...) above
postsRef.push({
  author: 'gracehop',
  title: 'Announcing COBOL, a New Programming Language'
});;
Python
# This is equivalent to the calls to push().set(...) above
posts_ref.push({
    'author': 'gracehop',
    'title': 'Announcing COBOL, a New Programming Language'
})
Go
if _, err := postsRef.Push(ctx, &Post{
	Author: "gracehop",
	Title:  "Announcing COBOL, a New Programming Language",
}); err != nil {
	log.Fatalln("Error pushing child node:", err)
}

Push() tarafından oluşturulan benzersiz anahtarı alma

push() çağrısı yapıldığında yeni veri yolu için bir referans döndürülür. Bu yolu, anahtarı almak veya ona veri ayarlamak için kullanabilirsiniz. Aşağıdaki kod, yukarıdaki örnekle aynı verileri sağlar ancak artık oluşturulan benzersiz anahtara erişebiliriz:

Java
// Generate a reference to a new location and add some data using push()
DatabaseReference pushedPostRef = postsRef.push();

// Get the unique ID generated by a push()
String postId = pushedPostRef.getKey();
Node.js
// Generate a reference to a new location and add some data using push()
const newPostRef = postsRef.push();

// Get the unique key generated by push()
const postId = newPostRef.key;
Python
# Generate a reference to a new location and add some data using push()
new_post_ref = posts_ref.push()

# Get the unique key generated by push()
post_id = new_post_ref.key
Go
// Generate a reference to a new location and add some data using Push()
newPostRef, err := postsRef.Push(ctx, nil)
if err != nil {
	log.Fatalln("Error pushing child node:", err)
}

// Get the unique key generated by Push()
postID := newPostRef.Key

Gördüğünüz gibi, benzersiz anahtarın değerini push() referansınızdan alabilirsiniz.

Veri Alma ile ilgili bir sonraki bölümde, bu verilerin Firebase veritabanından nasıl okunacağını öğreneceğiz.

İşlem Verilerini Kaydetme

Artımlı sayaçlar gibi eşzamanlı değişikliklerle bozulabilecek karmaşık verilerle çalışırken SDK bir işlem işlemi sağlar.

Java ve Node.js'de, işlem işlemine iki geri çağırma (güncelleme işlevi) verirsiniz. ve isteğe bağlı tamamlama geri çağırması kullanılır. Python ve Go'da, işlem işlemi engelleyerek bu nedenle yalnızca güncelleme işlevini kabul eder.

Güncelleme işlevi, verilerin mevcut durumunu bağımsız değişken olarak alır ve yazmak istediğiniz yeni durumu döndürmesi gerekir. Örneğin, günlük yayınlarınızın belirli bir blog yayınına olumlu oy verdiğinizde aşağıdaki gibi bir işlem yazarsınız:

Java
DatabaseReference upvotesRef = ref.child("server/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes");
upvotesRef.runTransaction(new Transaction.Handler() {
  @Override
  public Transaction.Result doTransaction(MutableData mutableData) {
    Integer currentValue = mutableData.getValue(Integer.class);
    if (currentValue == null) {
      mutableData.setValue(1);
    } else {
      mutableData.setValue(currentValue + 1);
    }

    return Transaction.success(mutableData);
  }

  @Override
  public void onComplete(
      DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {
    System.out.println("Transaction completed");
  }
});
Node.js
const upvotesRef = db.ref('server/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes');
upvotesRef.transaction((current_value) => {
  return (current_value || 0) + 1;
});
Python
def increment_votes(current_value):
    return current_value + 1 if current_value else 1

upvotes_ref = db.reference('server/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes')
try:
    new_vote_count = upvotes_ref.transaction(increment_votes)
    print('Transaction completed')
except db.TransactionAbortedError:
    print('Transaction failed to commit')
Go
fn := func(t db.TransactionNode) (interface{}, error) {
	var currentValue int
	if err := t.Unmarshal(&currentValue); err != nil {
		return nil, err
	}
	return currentValue + 1, nil
}

ref := client.NewRef("server/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes")
if err := ref.Transaction(ctx, fn); err != nil {
	log.Fatalln("Transaction failed to commit:", err)
}

Yukarıdaki örnek, sayacın null olup olmadığını veya henüz artırılıp artırılmadığını kontrol eder. Varsayılan değer yazılmamışsa işlemler null ile çağrılabileceği için.

Yukarıdaki kod bir işlem işlevi olmadan çalıştırılmışsa ve iki müşteri bunu artırmaya çalıştıysa aynı anda her ikisi de yeni değer olarak 1 yazar. Bu durumda, iki yerine bir artış olur.

Ağ Bağlantısı ve Çevrimdışı Yazma

Firebase Node.js ve Java istemcileri, etkin verilerin kendi dahili sürümlerini korur. Veriler yazıldığında yerel sürüme yazılır. İstemci daha sonra bu verileri veritabanıyla senkronize eder diğer müşterilerle de "en iyi çaba" için .

Sonuç olarak, veritabanına yapılan tüm yazma işlemleri yerel etkinlikleri, bu verilere herhangi bir veri daha yazılmadan hemen tetikler. kontrol eder. Bu, Firebase kullanarak bir uygulama yazdığınızda uygulamanızın , ağ gecikmesinden veya internet bağlantısından bağımsız olarak yanıt vermeye devam edecek.

Bağlantı yeniden kurulduğunda, istemcinin "yakalaması" için uygun etkinlik grubunu alırız sunucu durumuyla tutarlı şekilde güncelleyin.

Verilerinizin Güvenliğini Sağlama

Firebase Realtime Database, hangi kullanıcıların farklı düğümlere okuma ve yazma erişimi olduğunu tanımlamanızı sağlayan bir güvenlik diline sahiptir. verileriniz. Bu konuyla ilgili daha fazla bilgiyi Verilerinizin Güvenliğini Sağlayın bölümünde bulabilirsiniz.