क्लाउड फायरस्टोर आईओएस कोडेलैब

1 अवलोकन

लक्ष्य

इस कोडलैब में आप स्विफ्ट में iOS पर एक फायरस्टोर-समर्थित रेस्तरां अनुशंसा ऐप बनाएंगे। आप जान जायेंगे कैसे:

  1. आईओएस ऐप से फायरस्टोर पर डेटा पढ़ें और लिखें
  2. रीयलटाइम में फायरस्टोर डेटा में बदलावों को सुनें
  3. फायरस्टोर डेटा को सुरक्षित करने के लिए फायरबेस प्रमाणीकरण और सुरक्षा नियमों का उपयोग करें
  4. जटिल फायरस्टोर क्वेरीज़ लिखें

आवश्यक शर्तें

इस कोडलैब को शुरू करने से पहले सुनिश्चित करें कि आपने इसे इंस्टॉल कर लिया है:

  • Xcode संस्करण 14.0 (या उच्चतर)
  • कोकोपोड्स 1.12.0 (या उच्चतर)

2. फायरबेस कंसोल प्रोजेक्ट बनाएं

प्रोजेक्ट में फायरबेस जोड़ें

  1. फायरबेस कंसोल पर जाएं।
  2. नया प्रोजेक्ट बनाएं चुनें और अपने प्रोजेक्ट को "फ़ायरस्टोर आईओएस कोडेलैब" नाम दें।

3. नमूना परियोजना प्राप्त करें

कोड डाउनलोड करें

नमूना प्रोजेक्ट की क्लोनिंग करके और प्रोजेक्ट निर्देशिका में pod update चलाकर शुरुआत करें:

git clone https://github.com/firebase/friendlyeats-ios
cd friendlyeats-ios
pod update

Xcode में FriendlyEats.xcworkspace खोलें और इसे (Cmd+R) चलाएँ। ऐप सही ढंग से संकलित होना चाहिए और लॉन्च पर तुरंत क्रैश हो जाना चाहिए, क्योंकि इसमें GoogleService-Info.plist फ़ाइल गुम है। हम अगले चरण में इसे ठीक कर देंगे.

फायरबेस सेट करें

नया फायरस्टोर प्रोजेक्ट बनाने के लिए दस्तावेज़ का पालन करें। एक बार जब आपको अपना प्रोजेक्ट मिल जाए, तो फायरबेस कंसोल से अपने प्रोजेक्ट की GoogleService-Info.plist फ़ाइल डाउनलोड करें और इसे Xcode प्रोजेक्ट के रूट पर खींचें। यह सुनिश्चित करने के लिए प्रोजेक्ट को फिर से चलाएँ कि ऐप सही ढंग से कॉन्फ़िगर हो गया है और लॉन्च पर क्रैश नहीं होता है। लॉग इन करने के बाद, आपको नीचे दिए गए उदाहरण की तरह एक खाली स्क्रीन देखनी चाहिए। यदि आप लॉग इन करने में असमर्थ हैं, तो सुनिश्चित करें कि आपने प्रमाणीकरण के तहत फायरबेस कंसोल में ईमेल/पासवर्ड साइन-इन विधि सक्षम कर दी है।

d5225270159c040b.png

4. फायरस्टोर पर डेटा लिखें

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

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

इससे पहले कि हम फायरस्टोर में डेटा जोड़ सकें, हमें रेस्तरां संग्रह का संदर्भ प्राप्त करना होगा। RestaurantsTableViewController.didTapPopulateButton(_:) विधि में आंतरिक for लूप में निम्नलिखित जोड़ें।

let collection = Firestore.firestore().collection("restaurants")

अब जबकि हमारे पास एक संग्रह संदर्भ है तो हम कुछ डेटा लिख ​​सकते हैं। हमारे द्वारा जोड़ी गई कोड की अंतिम पंक्ति के ठीक बाद निम्नलिखित जोड़ें:

let collection = Firestore.firestore().collection("restaurants")

// ====== ADD THIS ======
let restaurant = Restaurant(
  name: name,
  category: category,
  city: city,
  price: price,
  ratingCount: 0,
  averageRating: 0
)

collection.addDocument(data: restaurant.dictionary)

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

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

फायरबेस कंसोल के नियम टैब में निम्नलिखित नियम जोड़ें और फिर प्रकाशित करें पर क्लिक करें।

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      //
      // WARNING: These rules are insecure! We will replace them with
      // more secure rules later in the codelab
      //
      allow read, write: if request.auth != null;
    }
  }
}

हम बाद में सुरक्षा नियमों पर विस्तार से चर्चा करेंगे, लेकिन यदि आप जल्दी में हैं, तो सुरक्षा नियमों के दस्तावेज़ पर एक नज़र डालें।

ऐप चलाएं और साइन इन करें। फिर ऊपरी बाईं ओर " पॉप्युलेट " बटन पर टैप करें, जो रेस्तरां दस्तावेज़ों का एक बैच बनाएगा, हालांकि आप इसे अभी तक ऐप में नहीं देखेंगे।

इसके बाद, फायरबेस कंसोल में फायरस्टोर डेटा टैब पर जाएँ। अब आपको रेस्तरां संग्रह में नई प्रविष्टियाँ देखनी चाहिए:

स्क्रीन शॉट 2017-07-06 12.45.38 PM.png

बधाई हो, आपने अभी-अभी iOS ऐप से फायरस्टोर को डेटा लिखा है! अगले भाग में आप सीखेंगे कि फायरस्टोर से डेटा कैसे पुनर्प्राप्त करें और इसे ऐप में कैसे प्रदर्शित करें।

5. फायरस्टोर से डेटा प्रदर्शित करें

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

सबसे पहले, आइए उस क्वेरी का निर्माण करें जो रेस्तरां की डिफ़ॉल्ट, अनफ़िल्टर्ड सूची परोसेगी। RestaurantsTableViewController.baseQuery() के कार्यान्वयन पर एक नज़र डालें:

return Firestore.firestore().collection("restaurants").limit(to: 50)

यह क्वेरी "रेस्तरां" नामक शीर्ष-स्तरीय संग्रह के 50 रेस्तरां तक ​​पुनर्प्राप्त करती है। अब जब हमारे पास एक प्रश्न है, तो हमें फायरस्टोर से अपने ऐप में डेटा लोड करने के लिए एक स्नैपशॉट श्रोता संलग्न करना होगा। stopObserving() पर कॉल के तुरंत बाद निम्नलिखित कोड को RestaurantsTableViewController.observeQuery() विधि में जोड़ें।

listener = query.addSnapshotListener { [unowned self] (snapshot, error) in
  guard let snapshot = snapshot else {
    print("Error fetching snapshot results: \(error!)")
    return
  }
  let models = snapshot.documents.map { (document) -> Restaurant in
    if let model = Restaurant(dictionary: document.data()) {
      return model
    } else {
      // Don't use fatalError here in a real app.
      fatalError("Unable to initialize type \(Restaurant.self) with dictionary \(document.data())")
    }
  }
  self.restaurants = models
  self.documents = snapshot.documents

  if self.documents.count > 0 {
    self.tableView.backgroundView = nil
  } else {
    self.tableView.backgroundView = self.backgroundView
  }

  self.tableView.reloadData()
}

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

हमारे शब्दकोशों को संरचनाओं में मैप करने के बाद ( Restaurant.swift देखें), डेटा प्रदर्शित करना केवल कुछ दृश्य गुणों को निर्दिष्ट करने का मामला है। निम्नलिखित पंक्तियों को RestaurantTableViewCell.populate(restaurant:) में RestaurantsTableViewController.swift में जोड़ें।

nameLabel.text = restaurant.name
cityLabel.text = restaurant.city
categoryLabel.text = restaurant.category
starsView.rating = Int(restaurant.averageRating.rounded())
priceLabel.text = priceString(from: restaurant.price)

इस पॉप्युलेट विधि को तालिका दृश्य डेटा स्रोत की tableView(_:cellForRowAtIndexPath:) विधि से बुलाया जाता है, जो पहले से अलग-अलग तालिका दृश्य कोशिकाओं में मूल्य प्रकारों के संग्रह को मैप करने का ख्याल रखता है।

ऐप को फिर से चलाएं और सत्यापित करें कि जिन रेस्तरां को हमने पहले कंसोल में देखा था वे अब सिम्युलेटर या डिवाइस पर दिखाई दे रहे हैं। यदि आपने यह अनुभाग सफलतापूर्वक पूरा कर लिया है तो आपका ऐप अब क्लाउड फायरस्टोर के साथ डेटा पढ़ और लिख रहा है!

391c0259bf05ac25.png

6. डेटा को सॉर्ट करना और फ़िल्टर करना

वर्तमान में हमारा ऐप रेस्तरां की एक सूची प्रदर्शित करता है, लेकिन उपयोगकर्ता के लिए उनकी आवश्यकताओं के आधार पर फ़िल्टर करने का कोई तरीका नहीं है। इस अनुभाग में आप फ़िल्टरिंग सक्षम करने के लिए फायरस्टोर की उन्नत क्वेरी का उपयोग करेंगे।

यहां सभी डिम सम रेस्तरां लाने के लिए एक सरल क्वेरी का उदाहरण दिया गया है:

let filteredQuery = query.whereField("category", isEqualTo: "Dim Sum")

जैसा कि इसके नाम से पता चलता है, whereField(_:isEqualTo:) विधि हमारी क्वेरी को केवल संग्रह के उन सदस्यों को डाउनलोड कराएगी जिनके फ़ील्ड हमारे द्वारा निर्धारित प्रतिबंधों को पूरा करते हैं। इस मामले में, यह केवल उन्हीं रेस्तरां को डाउनलोड करेगा जहां category "Dim Sum" है।

इस ऐप में उपयोगकर्ता विशिष्ट क्वेरी बनाने के लिए कई फ़िल्टर श्रृंखलाबद्ध कर सकता है, जैसे "सैन फ्रांसिस्को में पिज़्ज़ा" या "लोकप्रियता द्वारा ऑर्डर किया गया लॉस एंजिल्स में समुद्री भोजन"।

RestaurantsTableViewController.swift खोलें और निम्न कोड ब्लॉक को query(withCategory:city:price:sortBy:) :

if let category = category, !category.isEmpty {
  filtered = filtered.whereField("category", isEqualTo: category)
}

if let city = city, !city.isEmpty {
  filtered = filtered.whereField("city", isEqualTo: city)
}

if let price = price {
  filtered = filtered.whereField("price", isEqualTo: price)
}

if let sortBy = sortBy, !sortBy.isEmpty {
  filtered = filtered.order(by: sortBy)
}

उपरोक्त स्निपेट उपयोगकर्ता इनपुट के आधार पर एकल कंपाउंड क्वेरी बनाने के लिए कई whereField और order क्लॉज़ जोड़ता है। अब हमारी क्वेरी केवल उन रेस्तरां को वापस करेगी जो उपयोगकर्ता की आवश्यकताओं से मेल खाते हैं।

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

Error fetching snapshot results: Error Domain=io.grpc Code=9 
"The query requires an index. You can create it here: https://console.firebase.google.com/project/project-id/database/firestore/indexes?create_composite=..." 
UserInfo={NSLocalizedDescription=The query requires an index. You can create it here: https://console.firebase.google.com/project/project-id/database/firestore/indexes?create_composite=...}

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

7. लेन-देन में डेटा लिखना

इस अनुभाग में, हम उपयोगकर्ताओं के लिए रेस्तरां में समीक्षाएँ सबमिट करने की क्षमता जोड़ देंगे। अब तक, हमारे सभी लेखन परमाणु और अपेक्षाकृत सरल रहे हैं। यदि उनमें से कोई भी त्रुटिपूर्ण है, तो हम संभवतः उपयोगकर्ता को उन्हें पुनः प्रयास करने या स्वचालित रूप से पुनः प्रयास करने के लिए संकेत देंगे।

किसी रेस्तरां में रेटिंग जोड़ने के लिए हमें कई बार पढ़ने और लिखने का समन्वय करना होगा। सबसे पहले रिव्यू ही सबमिट करना होगा और फिर रेस्टोरेंट की रेटिंग गिनती और औसत रेटिंग को अपडेट करना होगा। यदि इनमें से एक विफल हो जाता है, लेकिन दूसरा नहीं, तो हम एक असंगत स्थिति में रह जाते हैं, जहां हमारे डेटाबेस के एक हिस्से का डेटा दूसरे हिस्से के डेटा से मेल नहीं खाता है।

सौभाग्य से, फायरस्टोर लेनदेन कार्यक्षमता प्रदान करता है जो हमें एक ही परमाणु ऑपरेशन में कई बार पढ़ने और लिखने की सुविधा देता है, जिससे यह सुनिश्चित होता है कि हमारा डेटा सुसंगत बना रहे।

RestaurantDetailViewController.reviewController(_:didSubmitFormWithReview:) में सभी लेट घोषणाओं के नीचे निम्नलिखित कोड जोड़ें।

let firestore = Firestore.firestore()
firestore.runTransaction({ (transaction, errorPointer) -> Any? in

  // Read data from Firestore inside the transaction, so we don't accidentally
  // update using stale client data. Error if we're unable to read here.
  let restaurantSnapshot: DocumentSnapshot
  do {
    try restaurantSnapshot = transaction.getDocument(reference)
  } catch let error as NSError {
    errorPointer?.pointee = error
    return nil
  }

  // Error if the restaurant data in Firestore has somehow changed or is malformed.
  guard let data = restaurantSnapshot.data(),
        let restaurant = Restaurant(dictionary: data) else {

    let error = NSError(domain: "FireEatsErrorDomain", code: 0, userInfo: [
      NSLocalizedDescriptionKey: "Unable to write to restaurant at Firestore path: \(reference.path)"
    ])
    errorPointer?.pointee = error
    return nil
  }

  // Update the restaurant's rating and rating count and post the new review at the 
  // same time.
  let newAverage = (Float(restaurant.ratingCount) * restaurant.averageRating + Float(review.rating))
      / Float(restaurant.ratingCount + 1)

  transaction.setData(review.dictionary, forDocument: newReviewReference)
  transaction.updateData([
    "numRatings": restaurant.ratingCount + 1,
    "avgRating": newAverage
  ], forDocument: reference)
  return nil
}) { (object, error) in
  if let error = error {
    print(error)
  } else {
    // Pop the review controller on success
    if self.navigationController?.topViewController?.isKind(of: NewReviewViewController.self) ?? false {
      self.navigationController?.popViewController(animated: true)
    }
  }
}

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

8. सुरक्षा नियम

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

सबसे पहले, आइए उन सुरक्षा नियमों पर गहराई से नज़र डालें जो हमने कोडलैब की शुरुआत में लिखे थे। फ़ायरबेस कंसोल खोलें और फ़ायरस्टोर टैब में डेटाबेस > नियमों पर जाएँ।

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      // Only authenticated users can read or write data
      allow read, write: if request.auth != null;
    }
  }
}

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

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

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /restaurants/{any}/ratings/{rating} {
      // Users can only write ratings with their user ID
      allow read;
      allow write: if request.auth != null 
                   && request.auth.uid == request.resource.data.userId;
    }
  
    match /restaurants/{any} {
      // Only authenticated users can read or write data
      allow read, write: if request.auth != null;
    }
  }
}

पहला मिलान विवरण restaurants संग्रह से संबंधित किसी भी दस्तावेज़ की उपसंग्रह नामित ratings से मेल खाता है। यदि समीक्षा की उपयोगकर्ता आईडी उपयोगकर्ता की उपयोगकर्ता आईडी से मेल नहीं खाती है तो सशर्त allow write किसी भी समीक्षा को सबमिट होने से रोकती है। दूसरा मिलान विवरण किसी भी प्रमाणित उपयोगकर्ता को डेटाबेस में रेस्तरां को पढ़ने और लिखने की अनुमति देता है।

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

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /restaurants/{restaurant} {
      match /ratings/{rating} {
        allow read: if request.auth != null;
        allow write: if request.auth != null 
                     && request.auth.uid == request.resource.data.userId;
      }
    
      allow read: if request.auth != null;
      allow create: if request.auth != null;
      allow update: if request.auth != null
                    && request.resource.data.name == resource.data.name
                    && request.resource.data.city == resource.data.city
                    && request.resource.data.price == resource.data.price
                    && request.resource.data.category == resource.data.category;
    }
  }
}

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

सुरक्षा नियमों के साथ आप क्या कर सकते हैं, इसके बारे में अधिक जानने के लिए दस्तावेज़ पर एक नज़र डालें।

9. निष्कर्ष

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

फायरस्टोर के बारे में अधिक जानने के लिए, निम्नलिखित संसाधनों पर जाएँ: