Apple प्लैटफ़ॉर्म पर डेटा पढ़ें और लिखें

(ज़रूरी नहीं) Firebase Local Emulator Suite की मदद से प्रोटोटाइप बनाना और परफ़ॉर्मेंस की जांच करना

इससे पहले कि हम यह बताएं कि आपका ऐप्लिकेशन, Realtime Database से डेटा कैसे पढ़ता और उसमें डेटा कैसे लिखता है, आइए आपको टूल के एक सेट के बारे में बताते हैं. इसका इस्तेमाल, Realtime Database की सुविधाओं का प्रोटोटाइप बनाने और उनकी परफ़ॉर्मेंस की जांच करने के लिए किया जा सकता है: Firebase Local Emulator Suite. अगर अलग-अलग डेटा मॉडल आज़माए जा रहे हैं, सुरक्षा के नियमों को ऑप्टिमाइज़ किया जा रहा है या बैक-एंड के साथ इंटरैक्ट करने का सबसे किफ़ायती तरीका खोजा जा रहा है, तो लाइव सेवाओं को डिप्लॉय किए बिना स्थानीय तौर पर काम करना एक अच्छा विकल्प हो सकता है.

एक Realtime Database एम्युलेटर, Local Emulator Suite का हिस्सा है, जिसकी मदद से आपका ऐप्लिकेशन, एम्युलेट किए गए डेटाबेस के कॉन्टेंट और कॉन्फ़िगरेशन के साथ-साथ, एम्युलेट किए गए प्रोजेक्ट के संसाधनों (फ़ंक्शन, अन्य डेटाबेस, और सुरक्षा के नियम) के साथ इंटरैक्ट कर सकता है. हालांकि, यह ज़रूरी नहीं है.

Realtime Database एम्युलेटर का इस्तेमाल करने के लिए, आपको सिर्फ़ ये कुछ चरण पूरे करने होंगे:

  1. एम्युलेटर से कनेक्ट करने के लिए, अपने ऐप्लिकेशन के टेस्ट कॉन्फ़िगरेशन में कोड की एक लाइन जोड़ना.
  2. अपने स्थानीय प्रोजेक्ट डायरेक्ट्री के रूट से, firebase emulators:start चलाना.
  3. Realtime Database प्लैटफ़ॉर्म के एसडीके का इस्तेमाल करके, अपने ऐप्लिकेशन के प्रोटोटाइप कोड से कॉल करना. इसके अलावा, Realtime Database REST API का इस्तेमाल करना.Realtime DatabaseRealtime Database

के इस्तेमाल के बारे में ज़्यादा जानकारी उपलब्ध है.Realtime DatabaseCloud Functions आपको Local Emulator Suite परिचय के बारे में भी पढ़ना चाहिए.

FIRDatabaseReference पाना

डेटाबेस से डेटा पढ़ने या उसमें डेटा लिखने के लिए, आपको FIRDatabaseReference का एक इंस्टेंस चाहिए:

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
var ref: DatabaseReference!

ref = Database.database().reference()

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];

डेटा लिखना

इस दस्तावेज़ में, Firebase डेटा को पढ़ने और लिखने के बुनियादी तरीकों के बारे में बताया गया है.

Firebase डेटा को Database रेफ़रंस में लिखा जाता है. साथ ही, रेफ़रंस में एसिंक्रोनस लिसनर जोड़कर, इसे वापस पाया जाता है. डेटा की शुरुआती स्थिति के लिए, लिसनर एक बार ट्रिगर होता है. इसके अलावा, डेटा में बदलाव होने पर भी यह ट्रिगर होता है.

डेटा लिखने की बुनियादी कार्रवाइयां

डेटा लिखने की बुनियादी कार्रवाइयों के लिए, setValue का इस्तेमाल करके, किसी तय रेफ़रंस में डेटा सेव किया जा सकता है. इससे उस पाथ पर मौजूद मौजूदा डेटा बदल जाता है. इस तरीके का इस्तेमाल इन कामों के लिए किया जा सकता है:

  • उपलब्ध JSON टाइप के हिसाब से, ये टाइप पास किए जा सकते हैं:
    • NSString
    • NSNumber
    • NSDictionary
    • NSArray

उदाहरण के लिए, setValue का इस्तेमाल करके, किसी उपयोगकर्ता को इस तरह जोड़ा जा सकता है:

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
self.ref.child("users").child(user.uid).setValue(["username": username])

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
[[[self.ref child:@"users"] child:authResult.user.uid]
    setValue:@{@"username": username}];

setValue का इस तरह इस्तेमाल करने से, तय की गई जगह पर मौजूद डेटा बदल जाता है. इसमें चाइल्ड नोड भी शामिल हैं. हालांकि, पूरे ऑब्जेक्ट को फिर से लिखे बिना भी, किसी चाइल्ड को अपडेट किया जा सकता है. अगर आपको उपयोगकर्ताओं को अपनी प्रोफ़ाइल अपडेट करने की अनुमति देनी है, तो उपयोगकर्ता नाम को इस तरह अपडेट किया जा सकता है:

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
self.ref.child("users/\(user.uid)/username").setValue(username)

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
[[[[_ref child:@"users"] child:user.uid] child:@"username"] setValue:username];

डेटा पढ़ना

वैल्यू इवेंट सुनकर डेटा पढ़ना

किसी पाथ पर मौजूद डेटा को पढ़ने और उसमें होने वाले बदलावों को सुनने के लिए, FIRDatabaseReference के observeEventType:withBlock का इस्तेमाल करके, FIRDataEventTypeValue इवेंट देखें.

इवेंट टाइप आम तौर पर इस्तेमाल
FIRDataEventTypeValue किसी पाथ के पूरे कॉन्टेंट को पढ़ें और उसमें होने वाले बदलावों को सुनें.

किसी दिए गए पाथ पर मौजूद डेटा को पढ़ने के लिए, FIRDataEventTypeValue इवेंट का इस्तेमाल किया जा सकता है. यह इवेंट, डेटा की मौजूदा स्थिति के बारे में जानकारी देता है. लिसनर को जोड़ने पर, यह तरीका एक बार ट्रिगर होता है. इसके अलावा, डेटा में बदलाव होने पर भी यह ट्रिगर होता है. इसमें चाइल्ड डेटा भी शामिल है. इवेंट कॉलबैक को एक snapshot पास किया जाता है. इसमें उस जगह पर मौजूद सारा डेटा शामिल होता है. इसमें चाइल्ड डेटा भी शामिल है. अगर कोई डेटा नहीं है, तो exists() को कॉल करने पर स्नैपशॉट false दिखाता है. इसके अलावा, इसकी value प्रॉपर्टी को पढ़ने पर nil दिखाता है.

यहां एक सोशल ब्लॉगिंग ऐप्लिकेशन का उदाहरण दिया गया है. यह ऐप्लिकेशन, डेटाबेस से किसी पोस्ट की जानकारी वापस पा रहा है:

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
refHandle = postRef.observe(DataEventType.value, with: { snapshot in
  // ...
})

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
_refHandle = [_postRef observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
  NSDictionary *postDict = snapshot.value;
  // ...
}];

लिसनर को एक FIRDataSnapshot मिलता है. इसमें इवेंट के समय, डेटाबेस में तय की गई जगह पर मौजूद डेटा, इसकी value प्रॉपर्टी में शामिल होता है. वैल्यू को, NSDictionary जैसे सही नेटिव टाइप असाइन किए जा सकते हैं. अगर उस जगह पर कोई डेटा मौजूद नहीं है, तो value की वैल्यू nil होती है.

डेटा को एक बार पढ़ना

getData() का इस्तेमाल करके, डेटा को एक बार पढ़ना

एसडीके को डेटाबेस सर्वर के साथ इंटरैक्शन मैनेज करने के लिए डिज़ाइन किया गया है. इससे कोई फ़र्क़ नहीं पड़ता कि आपका ऐप्लिकेशन ऑनलाइन है या ऑफ़लाइन.

आम तौर पर, डेटा पढ़ने के लिए, ऊपर बताए गए वैल्यू इवेंट के तरीकों का इस्तेमाल करना चाहिए. इससे बैकएंड से डेटा में होने वाले अपडेट की सूचना मिलती है. इन तरीकों से, आपके इस्तेमाल और बिलिंग में कमी आती है. साथ ही, इन्हें ऑप्टिमाइज़ किया जाता है, ताकि आपके उपयोगकर्ताओं को ऑनलाइन और ऑफ़लाइन होने पर बेहतर अनुभव मिल सके.

अगर आपको डेटा की ज़रूरत सिर्फ़ एक बार है, तो डेटाबेस से डेटा का स्नैपशॉट पाने के लिए, getData() का इस्तेमाल किया जा सकता है. अगर किसी वजह से getData() सर्वर की वैल्यू नहीं दिखा पाता है, तो क्लाइंट, लोकल स्टोरेज कैश की जांच करेगा. अगर वैल्यू अब भी नहीं मिलती है, तो गड़बड़ी का मैसेज दिखेगा.

यहां डेटाबेस से, उपयोगकर्ता के सार्वजनिक तौर पर दिखने वाले उपयोगकर्ता नाम को एक बार वापस पाने का उदाहरण दिया गया है:

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
do {
  let snapshot = try await ref.child("users/\(uid)/username").getData()
  let userName = snapshot.value as? String ?? "Unknown"
} catch {
  print(error)
}

Objective-C

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
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;
}];

getData() का ज़रूरत से ज़्यादा इस्तेमाल करने से, बैंडविथ का इस्तेमाल बढ़ सकता है और परफ़ॉर्मेंस में कमी आ सकती है. इसे रोकने के लिए, ऊपर दिखाए गए तरीके से रीयलटाइम लिसनर का इस्तेमाल किया जा सकता है.

ऑब्ज़र्वर की मदद से, डेटा को एक बार पढ़ना

कुछ मामलों में, ऐसा हो सकता है कि आपको सर्वर पर अपडेट की गई वैल्यू की जांच करने के बजाय, लोकल कैश से वैल्यू तुरंत वापस चाहिए. ऐसे मामलों में, लोकल डिस्क कैश से डेटा तुरंत पाने के लिए, observeSingleEventOfType का इस्तेमाल किया जा सकता है.

यह उन डेटा के लिए काम का है जिन्हें सिर्फ़ एक बार लोड करने की ज़रूरत होती है और जिनके बार-बार बदलने की उम्मीद नहीं होती या जिन्हें ऐक्टिव लिसनिंग की ज़रूरत नहीं होती. उदाहरण के लिए, पिछले उदाहरणों में ब्लॉगिंग ऐप्लिकेशन, उपयोगकर्ता की प्रोफ़ाइल लोड करने के लिए इस तरीके का इस्तेमाल करता है. ऐसा तब होता है, जब उपयोगकर्ता कोई नई पोस्ट लिखता है:

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
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

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
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);
}];

डेटा अपडेट करना या मिटाना

खास फ़ील्ड अपडेट करना

किसी नोड के खास चाइल्ड में एक साथ डेटा लिखने के लिए, updateChildValues तरीके का इस्तेमाल करें. इससे अन्य चाइल्ड नोड पर मौजूद डेटा नहीं बदलेगा.

updateChildValues को कॉल करते समय, कुंजी के लिए पाथ तय करके, निचले लेवल के चाइल्ड की वैल्यू अपडेट की जा सकती हैं. अगर बेहतर तरीके से स्केल करने के लिए, डेटा को कई जगहों पर सेव किया जाता है, तो डेटा फ़ैन-आउट का इस्तेमाल करके, उस डेटा के सभी इंस्टेंस अपडेट किए जा सकते हैं. उदाहरण के लिए, कोई सोशल ब्लॉगिंग ऐप्लिकेशन, पोस्ट बना सकता है. साथ ही, उसे हाल की गतिविधि वाले फ़ीड और पोस्ट करने वाले उपयोगकर्ता की गतिविधि वाले फ़ीड में अपडेट कर सकता है. ऐसा करने के लिए, ब्लॉगिंग ऐप्लिकेशन इस तरह का कोड इस्तेमाल करता है:

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
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

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
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];

इस उदाहरण में, childByAutoId का इस्तेमाल करके, /posts/$postid पर सभी उपयोगकर्ताओं के लिए पोस्ट वाले नोड में एक पोस्ट बनाई जाती है. साथ ही, getKey() का इस्तेमाल करके, कुंजी वापस पाई जाती है. इसके बाद, कुंजी का इस्तेमाल करके, उपयोगकर्ता की पोस्ट में /user-posts/$userid/$postid पर दूसरी एंट्री बनाई जा सकती है.

इन पाथ का इस्तेमाल करके, JSON ट्री में कई जगहों पर एक साथ अपडेट किए जा सकते हैं. इसके लिए, updateChildValues को सिर्फ़ एक बार कॉल करना होगा. जैसे, इस उदाहरण में नई पोस्ट को दोनों जगहों पर बनाया गया है. इस तरह किए गए एक साथ अपडेट, एटॉमिक होते हैं. इसका मतलब है कि या तो सभी अपडेट सफल होते हैं या सभी अपडेट फ़ेल होते हैं.

पूरा होने पर सूचना देने वाला ब्लॉक जोड़ना

अगर आपको यह जानना है कि आपका डेटा कब सेव हुआ है, तो पूरा होने पर सूचना देने वाला ब्लॉक जोड़ा जा सकता है. setValue और updateChildValues, दोनों में पूरा होने पर सूचना देने वाला ब्लॉक जोड़ा जा सकता है. इसे तब कॉल किया जाता है, जब डेटाबेस में डेटा सेव हो जाता है. इस लिसनर की मदद से, यह ट्रैक किया जा सकता है कि कौनसा डेटा सेव हो गया है और कौनसा डेटा अब भी सिंक हो रहा है. अगर कॉल सफल नहीं हुआ, तो लिसनर को गड़बड़ी वाला ऑब्जेक्ट पास किया जाता है. इससे यह पता चलता है कि गड़बड़ी क्यों हुई.

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
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

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
[[[_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.");
  }
}];

डेटा मिटाना

डेटा मिटाने का सबसे आसान तरीका है कि उस डेटा की जगह के रेफ़रंस पर removeValue को कॉल किया जाए.

setValue या updateChildValues जैसी किसी अन्य डेटा लिखने की कार्रवाई के लिए, वैल्यू के तौर पर nil तय करके भी डेटा मिटाया जा सकता है. updateChildValues के साथ इस तरीके का इस्तेमाल करके, एपीआई को एक बार कॉल करके, कई चाइल्ड मिटाए जा सकते हैं.

लिसनर हटाना

ViewController से बाहर निकलने पर, ऑब्ज़र्वर अपने-आप डेटा सिंक करना बंद नहीं करते. अगर किसी ऑब्ज़र्वर को सही तरीके से नहीं हटाया जाता है, तो वह लोकल मेमोरी में डेटा सिंक करता रहता है. जब किसी ऑब्ज़र्वर की ज़रूरत नहीं होती है, तो उससे जुड़ा FIRDatabaseHandle, removeObserverWithHandle तरीके को पास करके उसे हटाएं.

किसी रेफ़रंस में कॉलबैक ब्लॉक जोड़ने पर, FIRDatabaseHandle वापस मिलता है. इन हैंडल का इस्तेमाल, कॉलबैक ब्लॉक को हटाने के लिए किया जा सकता है.

अगर किसी डेटाबेस रेफ़रंस में कई लिसनर जोड़े गए हैं, तो कोई इवेंट होने पर हर लिसनर को कॉल किया जाता है. उस जगह पर डेटा सिंक करना बंद करने के लिए, removeAllObservers तरीके को कॉल करके, किसी जगह पर मौजूद सभी ऑब्ज़र्वर को हटाना होगा.

किसी लिसनर पर removeObserverWithHandle या removeAllObservers को कॉल करने से, उसके चाइल्ड नोड पर रजिस्टर किए गए लिसनर अपने-आप नहीं हटते. उन्हें हटाने के लिए, आपको उन रेफ़रंस या हैंडल को भी ट्रैक करना होगा.

डेटा को लेन-देन के तौर पर सेव करना

अगर आपको ऐसे डेटा के साथ काम करना है जिसमें एक साथ कई बदलाव होने की वजह से गड़बड़ी हो सकती है, तो लेन-देन की कार्रवाई का इस्तेमाल किया जा सकता है. जैसे, बढ़ते क्रम में काउंटर. इस कार्रवाई के लिए, आपको दो तर्क देने होंगे: अपडेट फ़ंक्शन और पूरा होने पर सूचना देने वाला वैकल्पिक कॉलबैक. अपडेट फ़ंक्शन, डेटा की मौजूदा स्थिति को तर्क के तौर पर लेता है और नई स्थिति दिखाता है जिसे आपको लिखना है.

उदाहरण के लिए, सोशल ब्लॉगिंग ऐप्लिकेशन में, उपयोगकर्ताओं को पोस्ट को स्टार करने और अनस्टार करने की अनुमति दी जा सकती है. साथ ही, यह ट्रैक किया जा सकता है कि किसी पोस्ट को कितने स्टार मिले हैं. इसके लिए, यह तरीका अपनाएं:

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
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

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
[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);
  }
}];

लेन-देन का इस्तेमाल करने से, स्टार की संख्या गलत नहीं होती. ऐसा तब होता है, जब कई उपयोगकर्ता एक ही समय पर एक ही पोस्ट को स्टार करते हैं या क्लाइंट के पास पुराना डेटा होता है. FIRMutableData क्लास में मौजूद वैल्यू, पाथ के लिए क्लाइंट की आखिरी ज्ञात वैल्यू होती है. अगर कोई वैल्यू नहीं है, तो यह nil होती है. सर्वर, शुरुआती वैल्यू की तुलना अपनी मौजूदा वैल्यू से करता है. अगर वैल्यू मेल खाती हैं, तो लेन-देन स्वीकार करता है. अगर वैल्यू मेल नहीं खाती हैं, तो लेन-देन अस्वीकार करता है. अगर लेन-देन अस्वीकार कर दिया जाता है, तो सर्वर, क्लाइंट को मौजूदा वैल्यू दिखाता है. इसके बाद, क्लाइंट अपडेट की गई वैल्यू के साथ लेन-देन को फिर से करता है. यह तब तक दोहराया जाता है, जब तक लेन-देन स्वीकार नहीं किया जाता या बहुत ज़्यादा कोशिशें नहीं की जातीं.

सर्वर-साइड पर एटॉमिक तरीके से बढ़ोतरी

ऊपर दिए गए इस्तेमाल के उदाहरण में, हम डेटाबेस में दो वैल्यू लिख रहे हैं: पोस्ट को स्टार/अनस्टार करने वाले उपयोगकर्ता का आईडी और स्टार की संख्या में बढ़ोतरी. अगर हमें पहले से पता है कि उपयोगकर्ता पोस्ट को स्टार कर रहा है, तो लेन-देन के बजाय, एटॉमिक तरीके से बढ़ोतरी की कार्रवाई का इस्तेमाल किया जा सकता है.

Swift

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
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

ध्यान दें: Firebase का यह प्रॉडक्ट, App Clip टारगेट पर उपलब्ध नहीं है.
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];

इस कोड में लेन-देन की कार्रवाई का इस्तेमाल नहीं किया जाता. इसलिए, अगर कोई ऐसा अपडेट होता है जो इस कार्रवाई के साथ काम नहीं करता, तो यह अपने-आप फिर से नहीं चलता. हालांकि, बढ़ोतरी की कार्रवाई सीधे डेटाबेस सर्वर पर होती है. इसलिए, इसमें कोई गड़बड़ी नहीं होती.

अगर आपको ऐप्लिकेशन के हिसाब से होने वाली गड़बड़ियों का पता लगाना है और उन्हें अस्वीकार करना है, तो उस इस्तेमाल के उदाहरण के लिए, सुरक्षा के कस्टम नियम लिखने चाहिए. जैसे, किसी उपयोगकर्ता ने पहले से ही किसी पोस्ट को स्टार किया है और वह उसे फिर से स्टार कर रहा है.

ऑफ़लाइन होने पर डेटा के साथ काम करना

अगर किसी क्लाइंट का नेटवर्क कनेक्शन टूट जाता है, तो भी आपका ऐप्लिकेशन सही तरीके से काम करता रहेगा.

Firebase डेटाबेस से कनेक्ट किया गया हर क्लाइंट, ऐक्टिव डेटा का अपना इंटरनल वर्शन बनाए रखता है. डेटा लिखे जाने पर, उसे सबसे पहले इस लोकल वर्शन में लिखा जाता है. इसके बाद, Firebase क्लाइंट, उस डेटा को रिमोट डेटाबेस सर्वर और अन्य क्लाइंट के साथ "बेस्ट-एफ़र्ट" के आधार पर सिंक करता है.

नतीजतन, डेटाबेस में लिखे जाने वाले सभी डेटा से जुड़े लोकल इवेंट तुरंत ट्रिगर होते हैं. ऐसा सर्वर पर डेटा लिखे जाने से पहले होता है. इसका मतलब है कि नेटवर्क की लेटेन्सी या कनेक्टिविटी से कोई फ़र्क़ नहीं पड़ता, आपका ऐप्लिकेशन हमेशा काम करता रहता है.

कनेक्टिविटी फिर से चालू होने के बाद, आपके ऐप्लिकेशन को इवेंट का सही सेट मिलता है. इससे क्लाइंट, सर्वर की मौजूदा स्थिति के साथ सिंक हो जाता है. इसके लिए, आपको कोई कस्टम कोड लिखने की ज़रूरत नहीं होती.

ऑफ़लाइन होने पर काम करने की सुविधा के बारे में ज़्यादा जानने के लिए, ऑनलाइन और ऑफ़लाइन होने पर काम करने की सुविधाओं के बारे में ज़्यादा जानें लेख पढ़ें.

अगले चरण