(ज़रूरी नहीं) प्रोटोटाइप बनाना और Firebase Local Emulator Suite की मदद से टेस्ट करना
आपका ऐप्लिकेशन Realtime Database पर किस तरह से डेटा पढ़ता है और उसे कैसे लिखा जाता है, इस बारे में बात करने से पहले, चलिए, ऐसे टूल के बारे में जानते हैं जिनका इस्तेमाल Realtime Database को प्रोटोटाइप करने और उनकी जाँच करने के लिए किया जा सकता है फ़ंक्शन: Firebase Local Emulator Suite. अगर आपको कोई दूसरा डेटा आज़माना है, मॉडल, आपके सुरक्षा नियमों को ऑप्टिमाइज़ करके या सबसे सटीक तरीके से बैक-एंड से इंटरैक्ट करने का किफ़ायती तरीका, स्थानीय तौर पर काम करना काम हो सकता है. यह काम, लाइव सेवाओं को डिप्लॉय किए बिना किया जा सकता है.
एक Realtime Database एम्युलेटर, Local Emulator Suite का हिस्सा है, जो इससे आपका ऐप्लिकेशन, आपके डेटाबेस के एम्युलेट किए गए कॉन्टेंट और कॉन्फ़िगरेशन से इंटरैक्ट कर सकता है. जैसे: विकल्प के तौर पर, आपके एम्युलेट किए गए प्रोजेक्ट रिसोर्स (फ़ंक्शन, अन्य डेटाबेस, और सुरक्षा के नियम शामिल हैं).
Realtime Database एम्युलेटर को इस्तेमाल करने के लिए, आपको कुछ ही चरण पूरे करने होंगे:
- एम्युलेटर से कनेक्ट करने के लिए, अपने ऐप्लिकेशन के टेस्ट कॉन्फ़िगरेशन में कोड की एक लाइन जोड़ना.
- आपकी लोकल प्रोजेक्ट डायरेक्ट्री के रूट से,
firebase emulators:start
पर चल रहा है. - Realtime Database प्लैटफ़ॉर्म का इस्तेमाल करके, अपने ऐप्लिकेशन के प्रोटोटाइप कोड से कॉल करना हमेशा की तरह SDK टूल या Realtime Database REST API का इस्तेमाल करके इंस्टॉल करें.
Realtime Database और Cloud Functions से जुड़े सिलसिलेवार निर्देश उपलब्ध हैं. आपको Local Emulator Suite के बारे में जानकारी भी देखनी चाहिए.
FIRDatabaseReference पाएं
डेटाबेस से डेटा पढ़ने या उसमें बदलाव करने के लिए, आपको के इंस्टेंस की ज़रूरत होगी
FIRDatabaseReference
:
Swift
var ref: DatabaseReference! ref = Database.database().reference()
Objective-C
@property (strong, nonatomic) FIRDatabaseReference *ref; self.ref = [[FIRDatabase database] reference];
डेटा सेव करने की अनुमति दें
इस दस्तावेज़ में Firebase डेटा को पढ़ने और लिखने से जुड़ी बुनियादी जानकारी दी गई है.
Firebase डेटा को Database
रेफ़रंस में लिखा जाता है और इसे
रेफ़रंस के साथ एसिंक्रोनस लिसनर अटैच करना. लिसनर ट्रिगर हो गया है
एक बार डेटा की शुरुआती स्थिति के लिए और फिर कभी भी डेटा में बदलाव होता है.
लिखने से जुड़ी बुनियादी कार्रवाइयां
लिखने के बुनियादी काम करने के लिए, setValue
का इस्तेमाल करके किसी खास प्रोजेक्ट में डेटा सेव किया जा सकता है
संदर्भ शामिल होगा, जो उस पाथ के किसी भी मौजूदा डेटा को बदल देगा. इस तरीके का इस्तेमाल करके:
- उपलब्ध JSON टाइप के पास के टाइप इस तरह हैं:
NSString
NSNumber
NSDictionary
NSArray
उदाहरण के लिए, setValue
वाले किसी उपयोगकर्ता को इस तरह जोड़ा जा सकता है:
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
का इस तरह इस्तेमाल करने से, बताई गई जगह के डेटा को ओवरराइट कर दिया जाता है,
इसमें सभी चाइल्ड नोड शामिल हैं. हालांकि, बच्चे के खाते को इनके बिना भी अपडेट किया जा सकता है
पूरे ऑब्जेक्ट को फिर से लिखना. अगर आपको उपयोगकर्ताओं को उनकी प्रोफ़ाइल अपडेट करने की अनुमति देनी है
तो आप उपयोगकर्ता नाम को इस प्रकार अपडेट कर सकते हैं:
Swift
self.ref.child("users/\(user.uid)/username").setValue(username)
Objective-C
[[[[_ref child:@"users"] child:user.uid] child:@"username"] setValue:username];
डेटा पढ़ें
वैल्यू इवेंट को सुनकर डेटा देखना
पाथ पर डेटा पढ़ने और बदलावों को सुनने के लिए,
निगरानी करने के लिए FIRDatabaseReference
में से observeEventType:withBlock
FIRDataEventTypeValue
इवेंट.
इवेंट प्रकार | आम तौर पर इस्तेमाल |
---|---|
FIRDataEventTypeValue |
पाथ के पूरे कॉन्टेंट में हुए बदलावों को पढ़ और सुन सकता है. |
दिए गए पाथ के डेटा को पढ़ने के लिए, FIRDataEventTypeValue
इवेंट का इस्तेमाल किया जा सकता है,
क्योंकि यह इवेंट के समय मौजूद होती है. यह तरीका एक बार ट्रिगर होता है. ऐसा तब होता है, जब
लिसनर को हर बार अटैच किया जाता है. डेटा में, किसी भी बच्चे के डेटा को भी शामिल किया जाता है.
बदलाव. इवेंट कॉलबैक को एक snapshot
पास किया जाता है, जिसमें उसका पूरा डेटा होता है
जगह की जानकारी, जिसमें चाइल्ड डेटा शामिल है. अगर कोई डेटा नहीं है, तो स्नैपशॉट दिखेगा
value
प्रॉपर्टी पढ़ने के बाद, exists()
और nil
को कॉल करने पर false
.
निम्न उदाहरण में सोशल ब्लॉगिंग ऐप्लिकेशन डेटाबेस से एक पोस्ट के बारे में जानकारी:
Swift
refHandle = postRef.observe(DataEventType.value, with: { snapshot in // ... })
Objective-C
_refHandle = [_postRef observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) { NSDictionary *postDict = snapshot.value; // ... }];
सुनने वाले को एक FIRDataSnapshot
मिलता है, जिसमें तय किए गए
डेटाबेस में मौजूद लोकेशन की जानकारी, इवेंट के समय इसकी value
प्रॉपर्टी में मौजूद होती है. आपने लोगों तक पहुंचाया मुफ़्त में
वैल्यू को सही नेटिव टाइप को असाइन कर सकता है, जैसे कि NSDictionary
.
अगर जगह के लिए कोई डेटा मौजूद नहीं है, तो value
nil
है.
डेटा को एक बार पढ़ें
getData() का इस्तेमाल करके एक बार पढ़ें
SDK टूल को डेटाबेस सर्वर के साथ इंटरैक्शन को मैनेज करने के लिए डिज़ाइन किया गया है. इससे कोई फ़र्क़ नहीं पड़ता कि ऐप ऑनलाइन है या ऑफ़लाइन.
आम तौर पर, वैल्यू इवेंट की उन तकनीकों का इस्तेमाल करना चाहिए जिनके बारे में ऊपर बताया गया है. डेटा का इस्तेमाल कर सकता है. वे तकनीक आपके इस्तेमाल और बिलिंग को कम करता है. साथ ही, इन्हें आपके उपयोगकर्ताओं को बेहतरीन सेवा देने के लिए ऑप्टिमाइज़ किया गया है उन्हें ऑनलाइन और ऑफ़लाइन होने का अनुभव कैसे होता है.
अगर आपको सिर्फ़ एक बार डेटा की ज़रूरत है, तो getData()
का इस्तेमाल करके
डेटाबेस से डेटा इकट्ठा कर सकते हैं. अगर किसी वजह से getData()
,
तो क्लाइंट लोकल स्टोरेज कैश की जांच करेगा और गड़बड़ी दिखाएगा
का इस्तेमाल करें.
नीचे दिए गए उदाहरण में, उपयोगकर्ता के सार्वजनिक तौर पर इस्तेमाल किए जाने वाले उपयोगकर्ता नाम को वापस पाने के बारे में बताया गया है डेटाबेस से एक बार में इंपोर्ट करें:
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; }];
getData()
का ग़ैर-ज़रूरी इस्तेमाल, बैंडविथ का इस्तेमाल बढ़ा सकता है और नुकसान पहुंचा सकता है
परफ़ॉर्मेंस का डेटा होता है. इसे रीयलटाइम लिसनर का इस्तेमाल करके रोका जा सकता है, जैसा कि दिखाया गया है
पढ़ें.
ऑब्ज़र्वर की मदद से एक बार डेटा पढ़ें
कुछ मामलों में हो सकता है कि आप लोकल कैश मेमोरी से वैल्यू दिखाना चाहें
वह भी तुरंत अपडेट हो जाएगा. उन में
तो आप observeSingleEventOfType
का इस्तेमाल करके
लोकल डिस्क कैश मेमोरी में सेव होने का विकल्प भी है.
यह ऐसे डेटा के लिए फ़ायदेमंद है जिसे सिर्फ़ एक बार लोड करने की ज़रूरत होती है और इसकी उम्मीद नहीं होती लगातार बदलते रहें या लगातार सुनने की सुविधा चालू करें. उदाहरण के लिए, ब्लॉगिंग ऐप्लिकेशन ऊपर दिए गए उदाहरणों में, इस तरीके का इस्तेमाल तब किया जाता है, जब किसी उपयोगकर्ता की प्रोफ़ाइल को लोड किया जाता है नई पोस्ट लिखना शुरू करें:
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); }];
डेटा अपडेट करना या मिटाना
खास फ़ील्ड अपडेट करें
अन्य को ओवरराइट किए बिना नोड के खास चिल्ड्रेन को एक साथ लिखने के लिए
चाइल्ड नोड के लिए, updateChildValues
तरीके का इस्तेमाल करें.
को दबाकर रखें
updateChildValues
को कॉल करते समय, लोअर-लेवल की चाइल्ड वैल्यू को इस तरह अपडेट किया जा सकता है
कुंजी के लिए पाथ तय कर रहा है. अगर डेटा को बढ़ाने के लिए कई जगहों पर सेव किया जाता है
बेहतर है, तो आप इसका इस्तेमाल करके उस डेटा के सभी इंस्टेंस को
डेटा फ़ैन-आउट का विकल्प चुनें. उदाहरण के लिए,
ऐसा हो सकता है कि सोशल ब्लॉगिंग ऐप्लिकेशन आपकी पोस्ट बनाने के साथ-साथ उसे अपडेट करके
हाल की गतिविधि फ़ीड और पोस्ट करने वाले उपयोगकर्ता की गतिविधि फ़ीड. ऐसा करने के लिए,
ब्लॉगिंग ऐप्लिकेशन इस तरह के कोड का इस्तेमाल करता है:
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];
इस उदाहरण में, इसके लिए पोस्ट वाले नोड में एक पोस्ट बनाने के लिए childByAutoId
का इस्तेमाल किया गया है
/posts/$postid
के सभी उपयोगकर्ता और साथ ही साथ कुंजी को
getKey()
. इसके बाद कुंजी का इस्तेमाल उपयोगकर्ता की
/user-posts/$userid/$postid
पर पोस्ट.
इन पाथ का इस्तेमाल करके, आप इसमें कई जगहों के लिए एक साथ अपडेट कर सकते हैं:
JSON ट्री, जिसे updateChildValues
को एक बार कॉल किया गया है, जैसे कि यह उदाहरण
दोनों स्थानों में नई पोस्ट बनाता है. इस तरह से एक साथ अपडेट किए जाते हैं
डेटा ऐटॉमिक हो जाता है: या तो सभी अपडेट सफल होते हैं या सभी अपडेट फ़ेल हो जाते हैं.
पूरा करने वाला ब्लॉक जोड़ें
अगर आपको यह जानना है कि आपका डेटा कब इंपोर्ट किया गया है, तो
पूरा होने वाला ब्लॉक. setValue
और updateChildValues
, दोनों विकल्प इस्तेमाल करते हैं
पूरा होने वाला ब्लॉक जिसे तब कॉल किया जाता है, जब राइट
डेटाबेस. इस लिसनर की मदद से, यह ट्रैक किया जा सकता है कि कौनसा डेटा
सेव किया गया है और कौनसा डेटा अब भी सिंक किया जा रहा है. अगर कॉल पूरा नहीं होता है,
लिसनर को गड़बड़ी वाला एक ऑब्जेक्ट पास किया जाता है. इसमें गड़बड़ी होने की वजह बताई जाती है.
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."); } }];
डेटा मिटाना
डेटा हटाने का सबसे आसान तरीका removeValue
को
की जगह पर हो सकता है.
किसी अन्य डेटा लिखने के लिए nil
को वैल्यू के तौर पर बताकर भी, डेटा को मिटाया जा सकता है
setValue
या updateChildValues
जैसी कार्रवाई. इस तकनीक का इस्तेमाल करके,
updateChildValues
का इस्तेमाल करके, एक एपीआई कॉल में कई बच्चों के नाम मिटाएं.
लिसनर को अलग करें
आपके किसी एक प्रॉम्प्ट को छोड़ने पर, ऑब्ज़र्वर अपने-आप डेटा सिंक करना बंद नहीं करते
ViewController
. अगर ऑब्ज़र्वर को ठीक से नहीं हटाया गया, तो वह सिंक होता रहेगा
डेटा को लोकल मेमोरी में सेव करना हो. जब ऑब्ज़र्वर की ज़रूरत न हो, तो पास करके उसे हटाएं
removeObserverWithHandle
तरीके से जुड़ी FIRDatabaseHandle
.
किसी पहचान फ़ाइल में कॉलबैक ब्लॉक जोड़ने पर, FIRDatabaseHandle
दिखता है.
इन हैंडल का इस्तेमाल कॉलबैक ब्लॉक को हटाने के लिए किया जा सकता है.
अगर डेटाबेस रेफ़रंस में एक से ज़्यादा लिसनर जोड़े गए हैं, तो हर लिसनर
किसी इवेंट के शुरू होने पर कॉल किया जाता है. उस जगह पर डेटा सिंक होने से रोकने के लिए,
आपको removeAllObservers
पर कॉल करके किसी जगह पर मौजूद सभी ऑब्ज़र्वर को हटाना होगा
तरीका.
लिसनर पर removeObserverWithHandle
या removeAllObservers
को कॉल करने से ऐसा होता है
अपने चाइल्ड नोड पर रजिस्टर किए गए लिसनर को अपने-आप नहीं हटाएं; आपको यह भी करना होगा
उन रेफ़रंस या हैंडल को हटाने के लिए उनका ट्रैक रखें.
डेटा को लेन-देन के तौर पर सेव करें
ऐसे डेटा के साथ काम करते समय जिसमें एक साथ गड़बड़ी हो सकती है जैसे कि इंंक्रीमेंटल काउंटर को शामिल किया है, तो लेन-देन की कार्रवाई. इस ऑपरेशन को दो आर्ग्युमेंट दिए जाते हैं: एक अपडेट फ़ंक्शन और एक वैकल्पिक फ़ंक्शन पूरा कॉलबैक. अपडेट फ़ंक्शन, डेटा की मौजूदा स्थिति को इस तरह लेता है तर्क के साथ हल करता है और वह नई मनचाहा स्थिति देता है, जिसे आप लिखना चाहते हैं.
उदाहरण के लिए, उदाहरण में दिए गए सोशल ब्लॉगिंग ऐप्लिकेशन में, उपयोगकर्ताओं को पोस्ट पर स्टार का निशान लगाएं या हटाएं. साथ ही, यह भी ट्रैक करें कि किसी पोस्ट को कितने स्टार मिले हैं इस तरह से:
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); } }];
लेन-देन का इस्तेमाल करने पर, अगर एक से ज़्यादा स्टार दिए गए हैं, तो स्टार काउंट गलत नहीं होगा
उपयोगकर्ताओं ने एक ही समय पर एक ही पोस्ट पर स्टार का निशान लगाया हो या क्लाइंट के पास पुराना डेटा हो. कॉन्टेंट बनाने
FIRMutableData
क्लास में शामिल वैल्यू, शुरुआत में क्लाइंट की आखिरी वैल्यू होती है
पथ के लिए ज्ञात मान या कोई न होने पर nil
. सर्वर,
अपने वर्तमान मान के प्रति प्रारंभिक मान और लेन-देन को स्वीकार करता है यदि
वैल्यू मेल खाती हैं या उसे अस्वीकार करती हैं. अगर ट्रांज़ैक्शन अस्वीकार हो जाता है, तो सर्वर
इससे क्लाइंट के लिए मौजूदा वैल्यू मिलती है, जो
अपडेट किया गया मान. लेन-देन स्वीकार किए जाने या तय सीमा से ज़्यादा बार लेन-देन पूरा होने तक, ऐसा होता रहेगा
कितनी बार कोशिश की जा चुकी है.
ऐटमिक सर्वर-साइड इंक्रीमेंट
ऊपर दिए गए इस्तेमाल के उदाहरण में, हम डेटाबेस में दो वैल्यू लिख रहे हैं: आईडी पोस्ट पर स्टार का निशान लगाने/अनस्टार का निशान लगाने वाले उपयोगकर्ता और बढ़ते हुए स्टार काउंट के बारे में जानकारी. अगर हम अगर उपयोगकर्ता पोस्ट पर स्टार का निशान लगा रहा है, तो हम ऐटोमिक इंक्रीमेंट का इस्तेमाल कर सकते हैं के बजाय कार्रवाई करता है.
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];
यह कोड किसी लेन-देन की कार्रवाई का इस्तेमाल नहीं करता है, इसलिए यह अपने-आप नहीं मिलता है यदि कोई विरोधात्मक अपडेट है तो फिर से चलाएं. हालांकि, बढ़ोतरी के बाद वाली कार्रवाई डेटाबेस सर्वर पर सीधे किया जाता है, तो किसी तरह के टकराव की संभावना नहीं होती.
अगर आपको ऐप्लिकेशन से जुड़े खास विवादों का पता लगाना और उन्हें अस्वीकार करना है, जैसे कि कोई उपयोगकर्ता जिस पोस्ट को वे पहले ही तारांकित कर चुके हैं, तो आपको अपने के सुरक्षा नियमों को लागू कर दिया है.
डेटा के साथ ऑफ़लाइन काम करना
अगर किसी क्लाइंट का इंटरनेट कनेक्शन बंद हो जाता है, तो आपका ऐप्लिकेशन काम करता रहेगा सही तरीके से.
Firebase डेटाबेस से जुड़े हर क्लाइंट का अपना इंटरनल वर्शन होता है सक्रिय डेटा का एक उदाहरण है. जब डेटा लिखा जाता है, तो वह इस लोकल वर्शन में लिखा जाता है चुनें. इसके बाद, Firebase क्लाइंट उस डेटा को रिमोट डेटाबेस के साथ सिंक करता है सर्वर और अन्य क्लाइंट के साथ "बेहतरीन कोशिश" करने पर आधार पर.
इस वजह से, डेटाबेस में मौजूद सभी कॉलम, लोकल इवेंट को ट्रिगर करते हैं किसी भी तरह का डेटा सर्वर पर सेव किया जाता है. इसका मतलब है कि आपका ऐप्लिकेशन फिर चाहे वह नेटवर्क में लगने वाले समय या कनेक्टिविटी की परवाह किए बिना रिस्पॉन्सिव हो.
कनेक्टिविटी वापस आने के बाद, आपके ऐप्लिकेशन को ज़रूरत के मुताबिक इवेंट दिखाए जाते हैं, ताकि क्लाइंट बिना किसी परेशानी के सर्वर की मौजूदा स्थिति के साथ सिंक हो जाए कोई कस्टम कोड लिखें.
हम ऑफ़लाइन व्यवहार के बारे में ऑनलाइन और ऑफ़लाइन सुविधाओं के बारे में ज़्यादा जानें.