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

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

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

रीयलटाइम डेटाबेस एम्युलेटर, एम्युलेटर सुइट का हिस्सा है. यह इससे आपका ऐप्लिकेशन, आपके डेटाबेस के एम्युलेट किए गए कॉन्टेंट और कॉन्फ़िगरेशन से इंटरैक्ट कर सकता है. जैसे: विकल्प के तौर पर, आपके एम्युलेट किए गए प्रोजेक्ट रिसोर्स (फ़ंक्शन, अन्य डेटाबेस, और सुरक्षा नियम).emulator_suite_short

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

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

रीयल टाइम डेटाबेस और Cloud Functions के बारे में ज़्यादा जानकारी उपलब्ध है. आपको Emulator Suite के बारे में जानकारी भी देखनी चाहिए.

DatabaseReference पाएं

डेटाबेस से डेटा पढ़ने या उसमें बदलाव करने के लिए, आपको के इंस्टेंस की ज़रूरत होगी DatabaseReference:

DatabaseReference ref = FirebaseDatabase.instance.ref();

डेटा सेव करने की अनुमति दें

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

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

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

लिखने के बुनियादी काम करने के लिए, set() का इस्तेमाल करके किसी खास प्रोजेक्ट में डेटा सेव किया जा सकता है संदर्भ दिया होता है, जो उस पाथ के किसी भी मौजूदा डेटा को बदल देता है. आपके पास रेफ़रंस सेट करने का विकल्प होता है से ये डेटा टाइप हो सकते हैं: String, boolean, int, double, Map, List.

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

DatabaseReference ref = FirebaseDatabase.instance.ref("users/123");

await ref.set({
  "name": "John",
  "age": 18,
  "address": {
    "line1": "100 Mountain View"
  }
});

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

DatabaseReference ref = FirebaseDatabase.instance.ref("users/123");

// Only update the name, leave the age and address!
await ref.update({
  "age": 19,
});

update() वाला तरीका, नोड के सब-पाथ को स्वीकार करता है, ताकि आप एक से ज़्यादा डेटाबेस में एक साथ नोड जोड़ना:

DatabaseReference ref = FirebaseDatabase.instance.ref("users");

await ref.update({
  "123/age": 19,
  "123/address/line1": "1 Mountain View",
});

डेटा पढ़ें

वैल्यू इवेंट को सुनकर डेटा देखना

पाथ पर डेटा पढ़ने और बदलावों को सुनने के लिए, सुनने के लिए, DatabaseReference की onValue प्रॉपर्टी DatabaseEvent सेकंड.

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

निम्न उदाहरण में सोशल ब्लॉगिंग ऐप्लिकेशन डेटाबेस से एक पोस्ट के बारे में नीचे दी गई जानकारी देखें:

DatabaseReference starCountRef =
        FirebaseDatabase.instance.ref('posts/$postId/starCount');
starCountRef.onValue.listen((DatabaseEvent event) {
    final data = event.snapshot.value;
    updateStarCount(data);
});

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

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

get() का इस्तेमाल करके एक बार पढ़ें

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

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

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

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

final ref = FirebaseDatabase.instance.ref();
final snapshot = await ref.child('users/$userId').get();
if (snapshot.exists) {
    print(snapshot.value);
} else {
    print('No data available.');
}

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

एक बार() की मदद से, डेटा को एक बार पढ़ें

कुछ मामलों में हो सकता है कि आप लोकल कैश मेमोरी से वैल्यू दिखाना चाहें वह भी तुरंत अपडेट हो जाएगा. उन में कुछ मामलों में आप once() का उपयोग करके स्थानीय डिस्क कैश से डेटा ले सकते हैं तुरंत.

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

final event = await ref.once(DatabaseEventType.value);
final username = event.snapshot.value?.username ?? 'Anonymous';

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

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

अन्य को ओवरराइट किए बिना नोड के खास चिल्ड्रेन को एक साथ लिखने के लिए चाइल्ड नोड के लिए, update() तरीके का इस्तेमाल करें.

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

void writeNewPost(String uid, String username, String picture, String title,
        String body) async {
    // A post entry.
    final postData = {
        'author': username,
        'uid': uid,
        'body': body,
        'title': title,
        'starCount': 0,
        'authorPic': picture,
    };

    // Get a key for a new Post.
    final newPostKey =
        FirebaseDatabase.instance.ref().child('posts').push().key;

    // Write the new post's data simultaneously in the posts list and the
    // user's post list.
    final Map<String, Map> updates = {};
    updates['/posts/$newPostKey'] = postData;
    updates['/user-posts/$uid/$newPostKey'] = postData;

    return FirebaseDatabase.instance.ref().update(updates);
}

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

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

पूरा होने वाला कॉलबैक जोड़ें

अगर आपको यह जानना है कि आपका डेटा कब एक्सपोर्ट किया जाएगा, तो पूरे होने वाले कॉलबैक. set() और update(), दोनों Future नतीजे दिखाते हैं, जिससे सफलता और गड़बड़ी वाले कॉलबैक अटैच किए जा सकते हैं, जिन्हें तब कॉल किया जाता है, जब लिखने के दौरान डेटाबेस से जुड़े होते हैं और जब कॉल सफल नहीं होता.

FirebaseDatabase.instance
    .ref('users/$userId/email')
    .set(emailAddress)
    .then((_) {
        // Data saved successfully!
    })
    .catchError((error) {
        // The write failed...
    });

डेटा मिटाना

डेटा हटाने का सबसे आसान तरीका यह है किremove() की जगह पर हो सकता है.

लिखने के लिए किसी अन्य कार्रवाई के लिए, वैल्यू के तौर पर शून्य दर्ज करके भी डेटा को मिटाया जा सकता है जैसे कि set() या update(). update() के साथ इस तकनीक का इस्तेमाल करके, एक एपीआई कॉल में कई चाइल्ड एंट्री मिटाएं.

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

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

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

void toggleStar(String uid) async {
  DatabaseReference postRef =
      FirebaseDatabase.instance.ref("posts/foo-bar-123");

  TransactionResult result = await postRef.runTransaction((Object? post) {
    // Ensure a post at the ref exists.
    if (post == null) {
      return Transaction.abort();
    }

    Map<String, dynamic> _post = Map<String, dynamic>.from(post as Map);
    if (_post["stars"] is Map && _post["stars"][uid] != null) {
      _post["starCount"] = (_post["starCount"] ?? 1) - 1;
      _post["stars"][uid] = null;
    } else {
      _post["starCount"] = (_post["starCount"] ?? 0) + 1;
      if (!_post.containsKey("stars")) {
        _post["stars"] = {};
      }
      _post["stars"][uid] = true;
    }

    // Return the new data.
    return Transaction.success(_post);
  });
}

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

await ref.runTransaction((Object? post) {
  // ...
}, applyLocally: false);

किसी लेन-देन का नतीजा TransactionResult है, जिसमें जानकारी होती है जैसे कि लेन-देन पूरा हुआ या नहीं और नया स्नैपशॉट:

DatabaseReference ref = FirebaseDatabase.instance.ref("posts/123");

TransactionResult result = await ref.runTransaction((Object? post) {
  // ...
});

print('Committed? ${result.committed}'); // true / false
print('Snapshot? ${result.snapshot}'); // DataSnapshot

लेन-देन रद्द करना

अगर आप सुरक्षित तरीके से लेन-देन रद्द करना चाहते हैं, तो Transaction.abort() को कॉल करें AbortTransactionException फेंकें:

TransactionResult result = await ref.runTransaction((Object? user) {
  if (user !== null) {
    return Transaction.abort();
  }

  // ...
});

print(result.committed); // false

ऐटमिक सर्वर-साइड इंक्रीमेंट

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

void addStar(uid, key) async {
  Map<String, Object?> updates = {};
  updates["posts/$key/stars/$uid"] = true;
  updates["posts/$key/starCount"] = ServerValue.increment(1);
  updates["user-posts/$key/stars/$uid"] = true;
  updates["user-posts/$key/starCount"] = ServerValue.increment(1);
  return FirebaseDatabase.instance.ref().update(updates);
}

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

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

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

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

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

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

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

हम ऑफ़लाइन व्यवहार के बारे में ऑनलाइन और ऑफ़लाइन सुविधाओं के बारे में ज़्यादा जानें.

अगले चरण