ডেটা সংরক্ষণ করা হচ্ছে

এই ডকুমেন্টটি আপনার Firebase Realtime Database ডেটা লেখার চারটি পদ্ধতি কভার করে: সেট, আপডেট, পুশ এবং লেনদেন সহায়তা।

ডেটা সংরক্ষণের উপায়

সেট একটি নির্দিষ্ট পাথে ডেটা লিখুন বা প্রতিস্থাপন করুন, যেমন messages/users/<username>
আপডেট সমস্ত ডেটা প্রতিস্থাপন না করে একটি নির্ধারিত পথের জন্য কিছু কী আপডেট করুন
ধাক্কা দেওয়া ডাটাবেসের ডেটা তালিকায় যোগ করুন । প্রতিবার যখন আপনি একটি তালিকায় একটি নতুন নোড পুশ করেন, তখন আপনার ডাটাবেস একটি অনন্য কী তৈরি করে, যেমন messages/users/<unique-user-id>/<username>
লেনদেন সমসাময়িক আপডেটের ফলে দূষিত হতে পারে এমন জটিল ডেটা নিয়ে কাজ করার সময় লেনদেন ব্যবহার করুন

ডেটা সংরক্ষণ করা হচ্ছে

মৌলিক ডাটাবেস লেখার কাজ হল একটি সেট যা নির্দিষ্ট ডাটাবেস রেফারেন্সে নতুন ডেটা সংরক্ষণ করে, সেই পাথে বিদ্যমান যেকোনো ডেটা প্রতিস্থাপন করে। সেটটি বোঝার জন্য, আমরা একটি সহজ ব্লগিং অ্যাপ তৈরি করব। আপনার অ্যাপের ডেটা এই ডাটাবেস রেফারেন্সে সংরক্ষণ করা হয়:

জাভা
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("server/saving-data/fireblog");
নোড.জেএস
// 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');
পাইথন
# Import database module.
from firebase_admin import db

# Get a database reference to our blog.
ref = db.reference('server/saving-data/fireblog')
যাও
// 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")

শুরু করা যাক কিছু ব্যবহারকারীর তথ্য সংরক্ষণ করে। আমরা প্রতিটি ব্যবহারকারীর একটি অনন্য ব্যবহারকারীর নাম দিয়ে সংরক্ষণ করব, এবং আমরা তাদের পুরো নাম এবং জন্ম তারিখও সংরক্ষণ করব। যেহেতু প্রতিটি ব্যবহারকারীর একটি অনন্য ব্যবহারকারীর নাম থাকবে, তাই এখানে push পদ্ধতির পরিবর্তে set পদ্ধতি ব্যবহার করা যুক্তিসঙ্গত কারণ আপনার কাছে ইতিমধ্যেই কী আছে এবং একটি তৈরি করার প্রয়োজন নেই।

প্রথমে, আপনার ব্যবহারকারীর ডেটার জন্য একটি ডাটাবেস রেফারেন্স তৈরি করুন। তারপর set() / setValue() ব্যবহার করে ব্যবহারকারীর ব্যবহারকারীর নাম, পূর্ণ নাম এবং জন্মদিন সহ একটি ব্যবহারকারীর অবজেক্ট ডাটাবেসে সংরক্ষণ করুন। আপনি একটি স্ট্রিং, নম্বর, বুলিয়ান, null , array অথবা যেকোনো JSON অবজেক্ট set পাস করতে পারেন। null পাস করলে নির্দিষ্ট স্থানে ডেটা মুছে যাবে। এই ক্ষেত্রে আপনি এটিকে একটি অবজেক্ট পাস করবেন:

জাভা
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);
নোড.জেএস
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'
  }
});
পাইথন
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'
    }
})
যাও
// 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)
}

যখন একটি JSON অবজেক্ট ডাটাবেসে সংরক্ষণ করা হয়, তখন অবজেক্টের বৈশিষ্ট্যগুলি স্বয়ংক্রিয়ভাবে নেস্টেড পদ্ধতিতে ডাটাবেস চাইল্ড লোকেশনে ম্যাপ করা হয়। এখন আপনি যদি https://docs-examples.firebaseio.com/server/saving-data/fireblog/users/alanisawesome/full_name URL এ যান, তাহলে আমরা "Alan Turing" মানটি দেখতে পাব। আপনি সরাসরি চাইল্ড লোকেশনেও ডেটা সংরক্ষণ করতে পারেন:

জাভা
usersRef.child("alanisawesome").setValueAsync(new User("June 23, 1912", "Alan Turing"));
usersRef.child("gracehop").setValueAsync(new User("December 9, 1906", "Grace Hopper"));
নোড.জেএস
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'
});
পাইথন
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'
})
যাও
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)
}

উপরের দুটি উদাহরণ - একটি অবজেক্টের সাথে একই সময়ে উভয় মান লেখা এবং চাইল্ড লোকেশনে আলাদাভাবে লেখা - এর ফলে একই ডেটা আপনার ডাটাবেসে সংরক্ষণ করা হবে:

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

প্রথম উদাহরণটি শুধুমাত্র একটি ইভেন্ট ট্রিগার করবে যারা ডেটা দেখছে এমন ক্লায়েন্টদের উপর, যেখানে দ্বিতীয় উদাহরণটি দুটি ইভেন্ট ট্রিগার করবে। এটি মনে রাখা গুরুত্বপূর্ণ যে যদি ডেটা ইতিমধ্যেই usersRef এ বিদ্যমান থাকে, তাহলে প্রথম পদ্ধতিটি এটিকে ওভাররাইট করবে, তবে দ্বিতীয় পদ্ধতিটি কেবলমাত্র প্রতিটি পৃথক চাইল্ড নোডের মান পরিবর্তন করবে এবং usersRef এর অন্যান্য চাইল্ড নোডগুলিকে অপরিবর্তিত রাখবে।

সংরক্ষিত ডেটা আপডেট করা হচ্ছে

যদি আপনি একই সময়ে একটি ডাটাবেস অবস্থানের একাধিক শিশুতে অন্যান্য শিশু নোড ওভাররাইট না করে লিখতে চান, তাহলে আপনি নীচে দেখানো আপডেট পদ্ধতিটি ব্যবহার করতে পারেন:

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

hopperRef.updateChildrenAsync(hopperUpdates);
নোড.জেএস
const usersRef = ref.child('users');
const hopperRef = usersRef.child('gracehop');
hopperRef.update({
  'nickname': 'Amazing Grace'
});
পাইথন
hopper_ref = users_ref.child('gracehop')
hopper_ref.update({
    'nickname': 'Amazing Grace'
})
যাও
hopperRef := usersRef.Child("gracehop")
if err := hopperRef.Update(ctx, map[string]interface{}{
	"nickname": "Amazing Grace",
}); err != nil {
	log.Fatalln("Error updating child:", err)
}

এটি গ্রেসের ডেটা আপডেট করে তার ডাকনাম অন্তর্ভুক্ত করবে। আপনি যদি update এর পরিবর্তে set here ব্যবহার করতেন, তাহলে এটি আপনার hopperRef থেকে full_name এবং date_of_birth উভয়ই মুছে ফেলত।

Firebase Realtime Database মাল্টি-পাথ আপডেটগুলিকেও সমর্থন করে। এর অর্থ হল আপডেট এখন একই সময়ে আপনার ডাটাবেসের একাধিক স্থানে মান আপডেট করতে পারে, এটি একটি শক্তিশালী বৈশিষ্ট্য যা আপনাকে আপনার ডেটা ডিনরমালাইজ করতে সাহায্য করে। মাল্টি-পাথ আপডেট ব্যবহার করে, আপনি একই সময়ে গ্রেস এবং অ্যালান উভয়ের ডাকনাম যোগ করতে পারেন:

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

usersRef.updateChildrenAsync(userUpdates);
নোড.জেএস
const usersRef = ref.child('users');
usersRef.update({
  'alanisawesome/nickname': 'Alan The Machine',
  'gracehop/nickname': 'Amazing Grace'
});
পাইথন
users_ref.update({
    'alanisawesome/nickname': 'Alan The Machine',
    'gracehop/nickname': 'Amazing Grace'
})
যাও
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)
}

এই আপডেটের পর, অ্যালান এবং গ্রেস উভয়েরই ডাকনাম যুক্ত করা হয়েছে:

{
  "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"
    }
  }
}

মনে রাখবেন যে, পাথ সহ অবজেক্ট লিখে অবজেক্ট আপডেট করার চেষ্টা করলে ভিন্ন আচরণ দেখা দেবে। চলুন দেখে নেওয়া যাক যদি আপনি গ্রেস এবং অ্যালানকে এভাবে আপডেট করার চেষ্টা করেন তাহলে কী হবে:

জাভা
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);
নোড.জেএস
const usersRef = ref.child('users');
usersRef.update({
  'alanisawesome': {
    'nickname': 'Alan The Machine'
  },
  'gracehop': {
    'nickname': 'Amazing Grace'
  }
});
পাইথন
users_ref.update({
    'alanisawesome': {
        'nickname': 'Alan The Machine'
    },
    'gracehop': {
        'nickname': 'Amazing Grace'
    }
})
যাও
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)
}

এর ফলে ভিন্ন আচরণ দেখা দেয়, যথা পুরো /users নোড ওভাররাইট করা:

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

একটি সমাপ্তি কলব্যাক যোগ করা হচ্ছে

Node.js এবং Java Admin SDK-তে, যদি আপনি জানতে চান যে আপনার ডেটা কখন কমিট করা হয়েছে, তাহলে আপনি একটি কমপ্লিশন কলব্যাক যোগ করতে পারেন। এই SDK-তে সেট এবং আপডেট উভয় পদ্ধতিই একটি ঐচ্ছিক কমপ্লিশন কলব্যাক নেয় যা ডাটাবেসে রাইটিং কমিট করা হলে কল করা হয়। যদি কোনও কারণে কলটি ব্যর্থ হয়, তাহলে কলব্যাকটি একটি ত্রুটি বস্তু পাস করে যা ব্যর্থতার কারণ নির্দেশ করে। Python এবং Go Admin SDK-তে, সমস্ত রাইটিং মেথড ব্লক করা হয়। অর্থাৎ, রাইটিং মেথডগুলি ডাটাবেসে কমিট করা না হওয়া পর্যন্ত ফিরে আসে না।

জাভা
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.");
    }
  }
});
নোড.জেএস
dataRef.set('I\'m writing data', (error) => {
  if (error) {
    console.log('Data could not be saved.' + error);
  } else {
    console.log('Data saved successfully.');
  }
});

ডেটা তালিকা সংরক্ষণ করা হচ্ছে

ডেটা তালিকা তৈরি করার সময়, বেশিরভাগ অ্যাপ্লিকেশনের মাল্টি-ইউজার প্রকৃতির কথা মাথায় রাখা এবং সেই অনুযায়ী আপনার তালিকার কাঠামো সামঞ্জস্য করা গুরুত্বপূর্ণ। উপরের উদাহরণটি আরও বিশদে বর্ণনা করে, আসুন আপনার অ্যাপে ব্লগ পোস্ট যুক্ত করি। আপনার প্রথম প্রবৃত্তি হতে পারে স্বয়ংক্রিয়-বৃদ্ধিকারী পূর্ণসংখ্যা সূচক সহ শিশুদের সংরক্ষণের জন্য সেট ব্যবহার করা, যেমন নিম্নলিখিত:

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

যদি কোনও ব্যবহারকারী একটি নতুন পোস্ট যোগ করেন তবে এটি /posts/2 হিসাবে সংরক্ষণ করা হবে। শুধুমাত্র একজন লেখক পোস্ট যোগ করলে এটি কাজ করবে, তবে আপনার সহযোগী ব্লগিং অ্যাপ্লিকেশনে অনেক ব্যবহারকারী একই সময়ে পোস্ট যোগ করতে পারেন। যদি দুজন লেখক একই সাথে /posts/2 এ লেখেন, তাহলে একটি পোস্ট অন্যজন দ্বারা মুছে ফেলা হবে।

এই সমস্যা সমাধানের জন্য, Firebase ক্লায়েন্টরা একটি push() ফাংশন প্রদান করে যা প্রতিটি নতুন শিশুর জন্য একটি অনন্য কী তৈরি করে । অনন্য চাইল্ড কী ব্যবহার করে, একাধিক ক্লায়েন্ট লেখার দ্বন্দ্বের চিন্তা না করেই একই সময়ে একই স্থানে শিশুদের যুক্ত করতে পারে।

জাভা
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"));
নোড.জেএস
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'
});
পাইথন
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'
})
যাও
// 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)
}

অনন্য কীটি একটি টাইমস্ট্যাম্পের উপর ভিত্তি করে তৈরি করা হয়, তাই তালিকার আইটেমগুলি স্বয়ংক্রিয়ভাবে কালানুক্রমিকভাবে সাজানো হবে। যেহেতু Firebase প্রতিটি ব্লগ পোস্টের জন্য একটি অনন্য কী তৈরি করে, তাই একাধিক ব্যবহারকারী একই সময়ে একটি পোস্ট যোগ করলে কোনও লেখার দ্বন্দ্ব দেখা দেবে না। আপনার ডাটাবেস ডেটা এখন এইরকম দেখাচ্ছে:

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

জাভাস্ক্রিপ্ট, পাইথন এবং গো-তে, push() কল করার এবং তারপর অবিলম্বে set() কল করার ধরণ এতটাই সাধারণ যে Firebase SDK আপনাকে push() এ সরাসরি সেট করার জন্য ডেটা পাস করে নিম্নলিখিতভাবে এগুলি একত্রিত করতে দেয়:

জাভা
// No Java equivalent
নোড.জেএস
// This is equivalent to the calls to push().set(...) above
postsRef.push({
  author: 'gracehop',
  title: 'Announcing COBOL, a New Programming Language'
});;
পাইথন
# This is equivalent to the calls to push().set(...) above
posts_ref.push({
    'author': 'gracehop',
    'title': 'Announcing COBOL, a New Programming Language'
})
যাও
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() দ্বারা তৈরি অনন্য কী পাওয়া

push() কল করলে নতুন ডেটা পাথের একটি রেফারেন্স ফিরে আসবে, যা আপনি কী পেতে বা এতে ডেটা সেট করতে ব্যবহার করতে পারেন। নিম্নলিখিত কোডটি উপরের উদাহরণের মতো একই ডেটা তৈরি করবে, তবে এখন আমরা তৈরি করা অনন্য কীটিতে অ্যাক্সেস পাবো:

জাভা
// 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();
নোড.জেএস
// 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;
পাইথন
# 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
যাও
// 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

আপনি দেখতে পাচ্ছেন, আপনার push() রেফারেন্স থেকে আপনি অনন্য কীটির মান পেতে পারেন।

ডেটা পুনরুদ্ধারের পরবর্তী বিভাগে, আমরা শিখব কিভাবে ফায়ারবেস ডাটাবেস থেকে এই ডেটা পড়তে হয়।

লেনদেনের তথ্য সংরক্ষণ করা হচ্ছে

জটিল ডেটা নিয়ে কাজ করার সময় যা সমসাময়িক পরিবর্তনের মাধ্যমে দূষিত হতে পারে, যেমন ক্রমবর্ধমান কাউন্টার, SDK একটি লেনদেন অপারেশন প্রদান করে।

জাভা এবং নোড.জেএস-এ, আপনি লেনদেন অপারেশনকে দুটি কলব্যাক দেন: একটি আপডেট ফাংশন এবং একটি ঐচ্ছিক সমাপ্তি কলব্যাক। পাইথন এবং গো-তে, লেনদেন অপারেশন ব্লকিং হয় এবং তাই এটি কেবল আপডেট ফাংশন গ্রহণ করে।

আপডেট ফাংশনটি ডেটার বর্তমান অবস্থাকে একটি আর্গুমেন্ট হিসেবে গ্রহণ করে এবং আপনি যে নতুন পছন্দসই অবস্থা লিখতে চান তা ফিরিয়ে আনবে। উদাহরণস্বরূপ, যদি আপনি একটি নির্দিষ্ট ব্লগ পোস্টে আপভোটের সংখ্যা বাড়াতে চান, তাহলে আপনাকে নিম্নলিখিতভাবে একটি লেনদেন লিখতে হবে:

জাভা
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");
  }
});
নোড.জেএস
const upvotesRef = db.ref('server/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes');
upvotesRef.transaction((current_value) => {
  return (current_value || 0) + 1;
});
পাইথন
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')
যাও
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)
}

উপরের উদাহরণটি পরীক্ষা করে দেখে যে কাউন্টারটি null কিনা নাকি এখনও বৃদ্ধি করা হয়নি, যেহেতু কোনও ডিফল্ট মান লেখা না থাকলে লেনদেন null দিয়ে কল করা যেতে পারে।

যদি উপরের কোডটি কোনও লেনদেন ফাংশন ছাড়াই চালানো হত এবং দুটি ক্লায়েন্ট একই সাথে এটি বৃদ্ধি করার চেষ্টা করত, তাহলে তারা উভয়ই নতুন মান হিসাবে 1 লিখত, যার ফলে দুটির পরিবর্তে একটি বৃদ্ধি হত।

নেটওয়ার্ক সংযোগ এবং অফলাইন লেখা

Firebase Node.js এবং জাভা ক্লায়েন্টরা যেকোনো সক্রিয় ডেটার নিজস্ব অভ্যন্তরীণ সংস্করণ বজায় রাখে। যখন ডেটা লেখা হয়, তখন প্রথমে এটি এই স্থানীয় সংস্করণে লেখা হয়। ক্লায়েন্ট তারপর সেই ডেটা ডাটাবেসের সাথে এবং অন্যান্য ক্লায়েন্টদের সাথে 'সর্বোত্তম প্রচেষ্টা' ভিত্তিতে সিঙ্ক্রোনাইজ করে।

ফলস্বরূপ, ডাটাবেসে লেখা সমস্ত লেখা স্থানীয় ইভেন্টগুলিকে অবিলম্বে ট্রিগার করবে, এমনকি কোনও ডেটা ডাটাবেসে লেখার আগেই। এর অর্থ হল যখন আপনি Firebase ব্যবহার করে একটি অ্যাপ্লিকেশন লিখবেন, তখন নেটওয়ার্ক ল্যাটেন্সি বা ইন্টারনেট সংযোগ নির্বিশেষে আপনার অ্যাপটি প্রতিক্রিয়াশীল থাকবে।

একবার সংযোগ পুনঃস্থাপিত হয়ে গেলে, আমরা উপযুক্ত ইভেন্টগুলির সেট পাব যাতে ক্লায়েন্ট কোনও কাস্টম কোড না লিখেই বর্তমান সার্ভারের অবস্থা "ক্যাচ" করতে পারে।

আপনার ডেটা সুরক্ষিত করা

Firebase Realtime Database একটি নিরাপত্তা ভাষা রয়েছে যা আপনাকে নির্ধারণ করতে দেয় যে কোন ব্যবহারকারীরা আপনার ডেটার বিভিন্ন নোডে পড়ার এবং লেখার অ্যাক্সেস পেয়েছে। আপনি এটি সম্পর্কে আরও পড়তে পারেন "আপনার ডেটা সুরক্ষিত করুন" বিভাগে।