Cloud Firestore iOS कोडलैब (कोड बनाना सीखना)

Cloud Firestore iOS कोडलैब

इस कोडलैब (कोड बनाना सीखने के लिए ट्यूटोरियल) के बारे में जानकारी

subjectपिछली बार जन॰ 23, 2025 को अपडेट किया गया
account_circleकिसी Googler ने लिखा है

1. खास जानकारी

लक्ष्य

इस कोडलैब में, आपको iOS पर Swift में, रेस्टोरेंट के सुझाव देने वाला Firestore ऐप्लिकेशन बनाना होगा. आपको इनके बारे में जानकारी मिलेगी:

  1. iOS ऐप्लिकेशन से Firestore में डेटा पढ़ना और उसमें डेटा डालना
  2. Firestore डेटा में होने वाले बदलावों को रीयल टाइम में सुनना
  3. Firestore डेटा को सुरक्षित रखने के लिए, Firebase Authentication और सुरक्षा से जुड़े नियमों का इस्तेमाल करना
  4. Firestore की जटिल क्वेरी लिखना

ज़रूरी शर्तें

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

  • Xcode का 14.0 या इसके बाद का वर्शन
  • CocoaPods 1.12.0 (या इसके बाद का वर्शन)

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

प्रोजेक्ट में Firebase जोड़ना

  1. Firebase कंसोल पर जाएं.
  2. नया प्रोजेक्ट बनाएं को चुनें और अपने प्रोजेक्ट का नाम "Firestore iOS Codelab" रखें.

3. सैंपल प्रोजेक्ट पाना

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

सबसे पहले, सैंपल प्रोजेक्ट को क्लोन करें और प्रोजेक्ट डायरेक्ट्री में pod update चलाएं:

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

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

Firebase सेट अप करना

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

d5225270159c040b.png

4. Firestore में डेटा सेव करना

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

हमारे ऐप्लिकेशन में मुख्य मॉडल ऑब्जेक्ट, रेस्टोरेंट है. Firestore का डेटा, दस्तावेज़ों, कलेक्शन, और सब-कलेक्शन में बांटा जाता है. हम हर रेस्टोरेंट को restaurants नाम के टॉप-लेवल कलेक्शन में दस्तावेज़ के तौर पर सेव करेंगे. अगर आपको Firestore डेटा मॉडल के बारे में ज़्यादा जानना है, तो दस्तावेज़ में दस्तावेज़ों और कलेक्शन के बारे में पढ़ें.

Firestore में डेटा जोड़ने से पहले, हमें रेस्टोरेंट कलेक्शन का रेफ़रंस चाहिए. RestaurantsTableViewController.didTapPopulateButton(_:) तरीके में, इनर फ़ॉर लूप में यह जोड़ें.

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)

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

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

Firebase कंसोल के नियम टैब में, ये नियम जोड़ें. इसके बाद, पब्लिश करें पर क्लिक करें.

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

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

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

इसके बाद, Firebase कंसोल में Firestore डेटा टैब पर जाएं. अब आपको रेस्टोरेंट के कलेक्शन में नई एंट्री दिखेंगी:

Screen Shot 2017-07-06 at 12.45.38 PM.png

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

5. Firestore से डेटा दिखाना

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

सबसे पहले, रेस्टोरेंट की डिफ़ॉल्ट और बिना फ़िल्टर की गई सूची दिखाने वाली क्वेरी बनाते हैं. RestaurantsTableViewController.baseQuery() को लागू करने का तरीका देखें:

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

यह क्वेरी, "रेस्टोरेंट" नाम के टॉप-लेवल कलेक्शन के 50 रेस्टोरेंट तक को वापस लाती है. अब हमारे पास क्वेरी है. हमें Firestore से अपने ऐप्लिकेशन में डेटा लोड करने के लिए, स्नैपशॉट लिसनर अटैच करना होगा. 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()
}

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

अपनी डिक्शनरी को स्ट्रक्चर (Restaurant.swift देखें) पर मैप करने के बाद, डेटा दिखाने के लिए कुछ व्यू प्रॉपर्टी असाइन करना ही ज़रूरी है. RestaurantsTableViewController.swift में RestaurantTableViewCell.populate(restaurant:) में ये लाइनें जोड़ें.

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:) तरीके से कॉल किया जाता है. यह पहले से मौजूद वैल्यू टाइप के कलेक्शन को अलग-अलग टेबल व्यू सेल में मैप करता है.

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

391c0259bf05ac25.png

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

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

डिम सम वाले सभी रेस्टोरेंट फ़ेच करने के लिए, यहां एक आसान क्वेरी का उदाहरण दिया गया है:

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=...}

ऐसा इसलिए, क्योंकि Firestore को ज़्यादातर कंपाउंड क्वेरी के लिए इंडेक्स की ज़रूरत होती है. क्वेरी के लिए इंडेक्स की ज़रूरत होने पर, Firestore तेज़ी से काम करता रहता है. गड़बड़ी के मैसेज में दिए गए लिंक को खोलने पर, Firebase कंसोल में इंडेक्स बनाने का यूज़र इंटरफ़ेस (यूआई) अपने-आप खुल जाएगा. इसमें सही पैरामीटर पहले से भरे होंगे. Firestore में इंडेक्स के बारे में ज़्यादा जानने के लिए, दस्तावेज़ देखें.

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

इस सेक्शन में, हम उपयोगकर्ताओं को रेस्टोरेंट की समीक्षाएं सबमिट करने की सुविधा जोड़ेंगे. अब तक, हमारे सभी डेटा डालने के तरीके, एक-एक एलिमेंट वाले और आसान रहे हैं. अगर इनमें से किसी भी कार्रवाई में कोई गड़बड़ी होती है, तो हम उपयोगकर्ता को उसे फिर से करने के लिए कहेंगे या अपने-आप फिर से कोशिश करेंगे.

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

अच्छी बात यह है कि Firestore में लेन-देन की सुविधा उपलब्ध है. इसकी मदद से, एक ही बार में कई बार डेटा पढ़ा और लिखा जा सकता है. इससे यह पक्का होता है कि हमारा डेटा एक जैसा बना रहे.

RestaurantDetailViewController.reviewController(_:didSubmitFormWithReview:) में, let के सभी एलान के नीचे यह कोड जोड़ें.

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

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

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

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

सबसे पहले, कोडलैब की शुरुआत में लिखे गए सुरक्षा नियमों के बारे में ज़्यादा जानें. Firebase कंसोल खोलें और डेटाबेस > Firestore टैब में मौजूद नियम पर जाएं.

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

नियमों में मौजूद request वैरिएबल, सभी नियमों में उपलब्ध एक ग्लोबल वैरिएबल है. साथ ही, हमने जो शर्त जोड़ी है उससे यह पक्का होता है कि उपयोगकर्ताओं को कुछ भी करने की अनुमति देने से पहले, अनुरोध की पुष्टि की गई हो. इससे, पुष्टि न किए गए उपयोगकर्ता, आपके डेटा में बिना अनुमति के बदलाव करने के लिए, Firestore API का इस्तेमाल नहीं कर पाएंगे. यह एक अच्छी शुरुआत है, लेकिन Firestore के नियमों का इस्तेमाल करके, ज़्यादा बेहतर काम किए जा सकते हैं.

हम समीक्षा लिखने पर पाबंदी लगाना चाहते हैं, ताकि समीक्षा का User-ID, पुष्टि किए गए उपयोगकर्ता के आईडी से मेल खाए. इससे यह पक्का होता है कि उपयोगकर्ता एक-दूसरे के नाम पर काम न कर सकें और धोखाधड़ी वाली समीक्षा न कर सकें.

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

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

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. नतीजा

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

Firestore के बारे में ज़्यादा जानने के लिए, इन संसाधनों पर जाएं: