इस पेज का अनुवाद Cloud Translation API से किया गया है.
Switch to English

IOS पर डेटा पढ़ें और लिखें

एक FIRDatabaseReference प्राप्त करें

डेटाबेस से डेटा पढ़ने या लिखने के लिए, आपको FIRDatabaseReference का एक उदाहरण FIRDatabaseReference :

तीव्र

var ref: DatabaseReference!

ref = Database.database().reference()

उद्देश्य सी

@property (strong, nonatomic) FIRDatabaseReference *ref;

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

डेटा पढ़ना और लिखना

इस दस्तावेज़ में फायरबेस डेटा पढ़ने और लिखने की मूल बातें शामिल हैं।

Firebase डेटा को FIRDatabase संदर्भ में लिखा जाता है और संदर्भ में एक अतुल्यकालिक श्रोता को संलग्न करके पुनर्प्राप्त किया जाता है। श्रोता को डेटा की प्रारंभिक स्थिति के लिए एक बार ट्रिगर किया जाता है और फिर कभी भी डेटा बदल जाता है।

बुनियादी लेखन कार्य

मूल लेखन कार्यों के लिए, आप उस पथ पर किसी भी मौजूदा डेटा की जगह, निर्दिष्ट संदर्भ में डेटा को बचाने के लिए setValue का उपयोग कर सकते हैं। आप इस विधि का उपयोग कर सकते हैं:

  • पास प्रकार जो उपलब्ध JSON प्रकार के अनुरूप हैं:
    • NSString
    • NSNumber
    • NSDictionary
    • NSArray

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

तीव्र

self.ref.child("users").child(user.uid).setValue(["username": username])

उद्देश्य सी

[[[self.ref child:@"users"] child:authResult.user.uid]
    setValue:@{@"username": username}];

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

तीव्र

self.ref.child("users/\(user.uid)/username").setValue(username)

उद्देश्य सी

[[[[_ref child:@"users"] child:user.uid] child:@"username"] setValue:username];

मूल्य घटनाओं के लिए सुनो

, एक पथ पर डेटा पढ़ सकते हैं और बदलावों को सुनने के लिए उपयोग observeEventType:withBlock या observeSingleEventOfType:withBlock के तरीकों FIRDatabaseReference निरीक्षण करने के लिए FIRDataEventTypeValue घटनाओं।

घटना प्रकार विशिष्ट उपयोग
FIRDataEventTypeValue किसी पथ की संपूर्ण सामग्री में परिवर्तन के लिए पढ़ें और सुनें।

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

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

तीव्र

refHandle = postRef.observe(DataEventType.value, with: { (snapshot) in
  let postDict = snapshot.value as? [String : AnyObject] ?? [:]
  // ...
})

उद्देश्य सी

_refHandle = [_postRef observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
  NSDictionary *postDict = snapshot.value;
  // ...
}];

श्रोता को एक FIRDataSnapshot प्राप्त होता है जिसमें डेटाबेस में निर्दिष्ट स्थान पर उसकी value संपत्ति में घटना के समय डेटा होता है। आप मानों को उपयुक्त मूल प्रकार, जैसे NSDictionary को सौंप सकते हैं। यदि कोई डेटा स्थान पर मौजूद नहीं है, तो value nil

एक बार डेटा पढ़ें

कुछ मामलों में आप चाहते हैं कि कॉलबैक को एक बार कॉल किया जाए और फिर तुरंत हटा दिया जाए, जैसे कि यूआई तत्व को इनिशियलाइज़ करते समय जिसे आप बदलने की उम्मीद नहीं करते हैं। आप इस परिदृश्य को आसान बनाने के लिए observeSingleEventOfType विधि का उपयोग कर सकते हैं: ईवेंट कॉलबैक ने एक बार ट्रिगर जोड़ा और फिर दोबारा ट्रिगर नहीं किया।

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

तीव्र

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)
}

उद्देश्य सी

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

तीव्र

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)

उद्देश्य सी

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 दोनों एक वैकल्पिक समापन ब्लॉक लेते हैं, जिसे तब लिखा जाता है जब डेटाबेस के लिए लेखन किया गया हो। यह श्रोता यह जानने के लिए उपयोगी हो सकता है कि कौन सा डेटा सहेजा गया है और कौन सा डेटा अभी भी सिंक्रनाइज़ किया जा रहा है। यदि कॉल विफल था, तो श्रोता को एक त्रुटि ऑब्जेक्ट पास किया जाता है जो बताता है कि विफलता क्यों हुई।

तीव्र

ref.child("users").child(user.uid).setValue(["username": username]) {
  (error:Error?, ref:DatabaseReference) in
  if let error = error {
    print("Data could not be saved: \(error).")
  } else {
    print("Data saved successfully!")
  }
}

उद्देश्य सी

[[[_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 छोड़ते हैं तो पर्यवेक्षक डेटा को स्वचालित रूप से सिंक्रनाइज़ करना बंद नहीं करते ViewController । यदि कोई पर्यवेक्षक ठीक से हटाया नहीं गया है, तो यह डेटा को स्थानीय मेमोरी में सिंक करना जारी रखता है। जब एक पर्यवेक्षक की आवश्यकता नहीं होती है, तो इसे हटाएं संबंधित FIRDatabaseHandle को removeObserverWithHandle विधि से पास करके।

जब आप संदर्भ में कॉलबैक ब्लॉक जोड़ते हैं, तो एक FIRDatabaseHandle वापस आ जाता है। कॉलबैक ब्लॉक को हटाने के लिए इन हैंडल का उपयोग किया जा सकता है।

यदि एक डेटाबेस संदर्भ में कई श्रोताओं को जोड़ा गया है, तो प्रत्येक श्रोता को एक घटना के उठाए जाने पर बुलाया जाता है। उस स्थान पर डेटा समन्वयित करने को रोकने के लिए, आपको removeAllObservers विधि को कॉल करके किसी स्थान पर सभी पर्यवेक्षकों को निकालना होगा।

कॉलिंग removeObserverWithHandle या removeAllObservers एक श्रोता स्वचालित रूप से अपने बच्चे नोड्स पर पंजीकृत श्रोताओं को दूर नहीं करता पर; आपको उन्हें हटाने के लिए उन संदर्भों या हैंडल का भी ध्यान रखना होगा।

लेनदेन के रूप में डेटा सहेजें

जब ऐसे डेटा के साथ काम करना, जो समवर्ती संशोधनों, जैसे वृद्धिशील काउंटरों से दूषित हो सकता है, तो आप लेनदेन ऑपरेशन का उपयोग कर सकते हैं। आप इस ऑपरेशन को दो तर्क देते हैं: एक अपडेट फ़ंक्शन और एक वैकल्पिक पूर्ण कॉलबैक। अपडेट फ़ंक्शन डेटा की वर्तमान स्थिति को एक तर्क के रूप में लेता है और वह नया वांछित राज्य देता है जिसे आप लिखना चाहते हैं।

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

तीव्र

ref.runTransactionBlock({ (currentData: MutableData) -> TransactionResult in
  if var post = currentData.value as? [String : AnyObject], let uid = Auth.auth().currentUser?.uid {
    var stars: Dictionary<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)
  }
}

उद्देश्य सी

[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 । सर्वर वर्तमान मूल्य के खिलाफ प्रारंभिक मूल्य की तुलना करता है और यदि मान मेल खाता है या इसे अस्वीकार करता है तो लेनदेन को स्वीकार करता है। यदि लेन-देन अस्वीकार कर दिया जाता है, तो सर्वर क्लाइंट को वर्तमान मूल्य लौटाता है, जो अद्यतन मूल्य के साथ फिर से लेनदेन चलाता है। यह तब तक दोहराता है जब तक कि लेन-देन स्वीकार नहीं किया जाता है या बहुत सारे प्रयास किए गए हैं।

डेटा ऑफ़लाइन लिखें

यदि कोई क्लाइंट अपना नेटवर्क कनेक्शन खो देता है, तो आपका ऐप सही तरीके से काम करना जारी रखेगा।

फायरबेस डेटाबेस से जुड़ा प्रत्येक क्लाइंट किसी भी सक्रिय डेटा का अपना आंतरिक संस्करण रखता है। जब डेटा लिखा जाता है, तो यह पहले इस स्थानीय संस्करण में लिखा जाता है। Firebase क्लाइंट तब दूरस्थ डेटाबेस सर्वर और "सर्वश्रेष्ठ-प्रयास" के आधार पर अन्य क्लाइंट के साथ उस डेटा को सिंक्रनाइज़ करता है।

परिणामस्वरूप, सभी सर्वर पर स्थानीय घटनाओं को तुरंत लिखता है, इससे पहले कि सर्वर पर कोई डेटा लिखा जाए। इसका मतलब है कि नेटवर्क विलंबता या कनेक्टिविटी की परवाह किए बिना आपका ऐप उत्तरदायी है।

एक बार कनेक्टिविटी बहाल होने के बाद, आपके ऐप को घटनाओं का उपयुक्त सेट प्राप्त होता है, ताकि क्लाइंट किसी भी कस्टम कोड को लिखे बिना, वर्तमान सर्वर स्थिति के साथ सिंक हो जाए।

अगला कदम