ক্লাউড ফায়ারস্টোর আইওএস কোডল্যাব

লক্ষ্য

এই কোডল্যাবে আপনি সুইফটে iOS এ একটি Firestore- সমর্থিত রেস্তোরাঁ সুপারিশ অ্যাপ তৈরি করবেন। আপনি শিখবেন কিভাবে:

  1. একটি iOS অ্যাপ থেকে Firestore- এ ডেটা পড়ুন এবং লিখুন
  2. রিয়েলটাইমে ফায়ারস্টোর ডেটার পরিবর্তনগুলি শুনুন
  3. Firestore ডেটা সুরক্ষিত করতে Firebase প্রমাণীকরণ এবং নিরাপত্তা নিয়ম ব্যবহার করুন
  4. জটিল ফায়ারস্টোর প্রশ্ন লিখুন

পূর্বশর্ত

এই কোডল্যাব শুরু করার আগে নিশ্চিত করুন যে আপনি ইনস্টল করেছেন:

  • এক্সকোড সংস্করণ 8.3 (বা উচ্চতর)
  • কোকোপডস 1.2.1 (বা উচ্চতর)

প্রকল্পে Firebase যোগ করুন

  1. যান Firebase কনসোল
  2. নতুন প্রকল্প তৈরি করুন এবং আপনার প্রকল্পের "Firestore আইওএস Codelab" নাম নির্বাচন করুন।

কোডটি ডাউনলোড করুন

ক্লোন করে শুরু করুন নমুনা প্রকল্প এবং চলমান pod update প্রকল্পের ডিরেক্টরির মধ্যে:

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

ওপেন FriendlyEats.xcworkspace Xcode এবং এটি চালানোর (উঠলে Cmd + আর)। অ্যাপ্লিকেশন সঠিকভাবে কম্পাইল করা উচিত এবং অবিলম্বে লঞ্চ উপর বিপর্যস্ত যেহেতু এটি একটি অনুপস্থিত GoogleService-Info.plist ফাইল। আমরা পরবর্তী ধাপে এটি সংশোধন করব।

ফায়ারবেস সেট আপ করুন

অনুসরণ ডকুমেন্টেশন একটি নতুন Firestore প্রকল্পের তৈরি করুন। একবার আপনি আপনার প্রকল্পের পেয়েছেন, আপনার প্রকল্পের ডাউনলোড GoogleService-Info.plist থেকে ফাইল Firebase কনসোল Xcode প্রকল্পের রুট প্রয়োজন এবং টেনে আনুন। অ্যাপটি সঠিকভাবে কনফিগার করে এবং আর লঞ্চে ক্র্যাশ না হয় তা নিশ্চিত করতে প্রকল্পটি আবার চালান। লগ ইন করার পরে, আপনাকে নীচের উদাহরণের মতো একটি ফাঁকা পর্দা দেখতে হবে। আপনি যদি লগ ইন করতে অক্ষম হন, নিশ্চিত করুন যে আপনি প্রমাণীকরণের অধীনে ফায়ারবেস কনসোলে ইমেল/পাসওয়ার্ড সাইন-ইন পদ্ধতি সক্ষম করেছেন।

10a0671ce8f99704.png

এই বিভাগে আমরা ফায়ারস্টোরে কিছু ডেটা লিখব যাতে আমরা অ্যাপ UI তৈরি করতে পারি। এর মাধ্যমে নিজে কাজ করা যেতে পারে Firebase কনসোল , কিন্তু আমরা অ্যাপ্লিকেশন নিজেই একটি মৌলিক Firestore লেখার প্রকট এটা চেষ্টা করবো।

আমাদের অ্যাপের প্রধান মডেল বস্তু হল একটি রেস্টুরেন্ট। ফায়ারস্টোর ডেটা ডকুমেন্ট, কালেকশন এবং সাবকলেকশনে বিভক্ত। আমরা একটি টপ লেভেল সংগ্রহ নামক একটি নথি হিসাবে একে রেস্টুরেন্টে সংরক্ষণ করবে restaurants । আপনি 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)

উপরের কোডটি রেস্তোঁরা সংগ্রহে একটি নতুন নথি যুক্ত করেছে। ডকুমেন্টের ডেটা একটি অভিধান থেকে এসেছে, যা আমরা একটি রেস্টুরেন্ট স্ট্রাক্ট থেকে পাই।

আমরা প্রায় সেখানেই আছি - ফায়ারস্টোরে নথি লিখার আগে আমাদের ফায়ারস্টোরের নিরাপত্তা বিধিগুলি খুলতে হবে এবং আমাদের ডাটাবেসের কোন অংশগুলি ব্যবহারকারীদের দ্বারা লিখিত হওয়া উচিত তা বর্ণনা করতে হবে। আপাতত, আমরা কেবলমাত্র অনুমোদিত ব্যবহারকারীদের সম্পূর্ণ ডাটাবেসে পড়তে এবং লিখতে অনুমতি দেব। এটি একটি প্রোডাকশন অ্যাপের জন্য একটু বেশি অনুমতিপ্রাপ্ত, কিন্তু অ্যাপ-বিল্ডিং প্রক্রিয়ার সময় আমরা যথেষ্ট শিথিল কিছু চাই যাতে পরীক্ষা-নিরীক্ষার সময় আমরা ক্রমাগত প্রমাণীকরণের সমস্যায় না পড়ি। এই কোডল্যাব শেষে আমরা আপনার নিরাপত্তা বিধিমালা কিভাবে কঠোর করা যায় এবং অনিচ্ছাকৃত পড়া এবং লেখার সম্ভাবনাকে সীমাবদ্ধ করার বিষয়ে কথা বলব।

ইন বিধি ট্যাব Firebase কনসোলের নিম্নলিখিত নিয়মগুলি যোগ করতে পারেন এবং তারপর প্রকাশ করুন এ ক্লিক করুন।

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

আমরা বিস্তারিতভাবে নিরাপত্তা নিয়ম পরে আলোচনা করব, কিন্তু যদি আপনি তাড়ার মধ্যে আছেন, কটাক্ষপাত করা নিরাপত্তা নিয়ম ডকুমেন্টেশন

অ্যাপ্লিকেশন এবং সাইন চালান। তারপর উপরের বাম, যা রেস্টুরেন্টে কাগজপত্র একটি ব্যাচ তৈরি করবে মধ্যে "পূরণ" বাটনে ট্যাপ করুন, যদিও আপনি এখনও অ্যাপ্লিকেশান এ এই দেখতে পাবেন না।

এর পরে, নেভিগেট Firestore তথ্য ট্যাব Firebase কনসোলে। আপনি এখন রেস্টুরেন্ট সংগ্রহে নতুন এন্ট্রি দেখতে হবে:

স্ক্রিন শট 2017-07-06 12.45.38 PM.png এ

অভিনন্দন, আপনি একটি iOS অ্যাপ থেকে ফায়ারস্টোরে সবেমাত্র তথ্য লিখেছেন! পরবর্তী বিভাগে আপনি শিখবেন কিভাবে ফায়ারস্টোর থেকে ডেটা পুনরুদ্ধার করতে হবে এবং অ্যাপে এটি প্রদর্শন করতে হবে।

এই বিভাগে আপনি শিখবেন কিভাবে ফায়ারস্টোর থেকে ডেটা উদ্ধার করা যায় এবং অ্যাপে এটি প্রদর্শন করা যায়। দুটি মূল পদক্ষেপ হল একটি প্রশ্ন তৈরি করা এবং একটি স্ন্যাপশট শ্রোতা যুক্ত করা। এই শ্রোতাকে সমস্ত বিদ্যমান ডেটা সম্পর্কে অবহিত করা হবে যা ক্যোয়ারীর সাথে মেলে এবং রিয়েল টাইমে আপডেট পায়।

প্রথমে, আসুন প্রশ্নটি তৈরি করি যা রেস্তোঁরাগুলির ডিফল্ট, ফিল্টারবিহীন তালিকা সরবরাহ করবে। বাস্তবায়ন কটাক্ষপাত RestaurantsTableViewController.baseQuery() :

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

এই প্রশ্নটি "রেস্তোরাঁ" নামে শীর্ষ স্তরের সংগ্রহের 50 টি রেস্তোরাঁ উদ্ধার করে। এখন যেহেতু আমাদের একটি প্রশ্ন আছে, ফায়ারস্টোর থেকে আমাদের অ্যাপে ডেটা লোড করার জন্য আমাদের একটি স্ন্যাপশট লিসেনার সংযুক্ত করতে হবে। নিম্নলিখিত কোড যোগ করুন RestaurantsTableViewController.observeQuery() শুধু থেকে কল পর পদ্ধতি stopObserving()

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(_:) কল একটি স্ন্যাপশট শ্রোতা ক্যোয়ারী যে দৃশ্য নিয়ামক প্রত্যেক সময় ডেটা সার্ভারে পরিবর্তন আপডেট হবে যোগ করা। আমরা স্বয়ংক্রিয়ভাবে আপডেটগুলি পাই এবং ম্যানুয়ালি পরিবর্তনগুলি চাপাতে হবে না। মনে রাখবেন, এই স্ন্যাপশট শ্রোতাকে সার্ভার-সাইড পরিবর্তনের ফলে যেকোনো সময় আহ্বান করা যেতে পারে তাই আমাদের অ্যাপটি পরিবর্তনগুলি পরিচালনা করতে পারে তা গুরুত্বপূর্ণ।

আমাদের অভিধান ম্যাপিং structs মধ্যে (দেখুন পরে 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:) পৃথক টেবিল ভিউ কোষ সামনে পদ্ধতি, যা থেকে মান ধরনের সংগ্রহ ম্যাপিং যত্ন নেয়।

অ্যাপটি আবার চালান এবং যাচাই করুন যে আমরা রেস্তোরাঁগুলি আগে কনসোলে দেখেছি সেগুলি এখন সিমুলেটর বা ডিভাইসে দৃশ্যমান। আপনি যদি এই বিভাগটি সফলভাবে সম্পন্ন করেন তবে আপনার অ্যাপ এখন ক্লাউড ফায়ারস্টোর দিয়ে ডেটা পড়ছে এবং লিখছে!

2ca7f8c6052f7f79.png

বর্তমানে আমাদের অ্যাপ রেস্তোরাঁগুলির একটি তালিকা প্রদর্শন করে, কিন্তু ব্যবহারকারীর তাদের প্রয়োজনের ভিত্তিতে ফিল্টার করার কোন উপায় নেই। এই বিভাগে আপনি ফিল্টারিং সক্ষম করতে 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/testapp-5d356/database/firestore/indexes?create_index=..." 
UserInfo={NSLocalizedDescription=The query requires an index. You can create it here: https://console.firebase.google.com/project/project-id/database/firestore/indexes?create_index=...}

এর কারণ হল ফায়ারস্টোরের বেশিরভাগ যৌগিক প্রশ্নের জন্য সূচী প্রয়োজন। প্রশ্নের উপর সূচী প্রয়োজন ফায়ারস্টোর স্কেলে দ্রুত রাখে। ত্রুটি বার্তা থেকে লিঙ্ক খোলা স্বয়ংক্রিয়ভাবে ঠিক পূরণ পরামিতি সঙ্গে Firebase কনসোলে সূচক সৃষ্টি UI 'তে খুলবে।, Firestore মধ্যে ইনডেক্স সম্পর্কে আরো জানতে ডকুমেন্টেশন যান

এই বিভাগে, আমরা ব্যবহারকারীদের রেস্টুরেন্টগুলিতে পর্যালোচনা জমা দেওয়ার ক্ষমতা যোগ করব। এই পর্যন্ত, আমাদের সমস্ত লেখা পারমাণবিক এবং অপেক্ষাকৃত সহজ ছিল। যদি তাদের মধ্যে কেউ ভুল করে, আমরা সম্ভবত ব্যবহারকারীকে তাদের পুনরায় চেষ্টা করতে বা স্বয়ংক্রিয়ভাবে পুনরায় চেষ্টা করার জন্য অনুরোধ করব।

একটি রেস্তোরাঁয় একটি রেটিং যোগ করার জন্য আমাদের একাধিক পড়া এবং লেখার সমন্বয় করতে হবে। প্রথমে রিভিউ নিজেই জমা দিতে হবে, এবং তারপর রেস্তোরাঁর রেটিং গণনা এবং গড় রেটিং আপডেট করতে হবে। যদি এইগুলির মধ্যে একটি ব্যর্থ হয় কিন্তু অন্যটি না হয়, আমরা একটি অসঙ্গত অবস্থায় রয়েছি যেখানে আমাদের ডাটাবেসের এক অংশের ডেটা অন্য ডেটার সাথে মেলে না।

সৌভাগ্যবশত, ফায়ারস্টোর লেনদেনের কার্যকারিতা প্রদান করে যা আমাদের একক পারমাণবিক অপারেশনে একাধিক রিড এবং রাইট করতে দেয়, যাতে আমাদের ডেটা সামঞ্জস্যপূর্ণ থাকে।

সমস্ত এলইটি ঘোষণা নিচের কোড যোগ করুন 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)
    }
  }
}

আপডেট ব্লকের ভিতরে, লেনদেন বস্তু ব্যবহার করে আমরা যে সমস্ত ক্রিয়াকলাপ করি তা ফায়ারস্টোর দ্বারা একক পারমাণবিক আপডেট হিসাবে বিবেচিত হবে। সার্ভারে আপডেট ব্যর্থ হলে, Firestore স্বয়ংক্রিয়ভাবে এটি কয়েকবার পুনরায় চেষ্টা করবে। এর মানে হল যে আমাদের ত্রুটির অবস্থা সম্ভবত একটি ত্রুটি বারবার ঘটছে, উদাহরণস্বরূপ যদি ডিভাইসটি সম্পূর্ণ অফলাইন থাকে বা ব্যবহারকারী যে পথে তারা লেখার চেষ্টা করছে সে পথে লেখার জন্য অনুমোদিত নয়।

আমাদের অ্যাপের ব্যবহারকারীরা আমাদের ডাটাবেসে থাকা প্রতিটি তথ্য পড়তে এবং লিখতে পারবে না। উদাহরণস্বরূপ প্রত্যেকেরই একটি রেস্তোরাঁর রেটিং দেখতে সক্ষম হওয়া উচিত, কিন্তু শুধুমাত্র একজন অনুমোদিত ব্যবহারকারীকে একটি রেটিং পোস্ট করার অনুমতি দেওয়া উচিত। ক্লায়েন্টের জন্য ভাল কোড লেখার জন্য এটি যথেষ্ট নয়, সম্পূর্ণ নিরাপদ হওয়ার জন্য আমাদের ব্যাক -এন্ডে আমাদের ডেটা সিকিউরিটি মডেল নির্দিষ্ট করতে হবে। এই বিভাগে আমরা শিখব কিভাবে আমাদের ডেটা সুরক্ষার জন্য ফায়ারবেস নিরাপত্তা নিয়ম ব্যবহার করতে হয়।

প্রথমে, কোডল্যাবের শুরুতে আমরা যে নিরাপত্তা বিধিগুলি লিখেছিলাম সেগুলি গভীরভাবে দেখে নেওয়া যাক। থেকে Firebase কনসোল এবং তা নেভিগেট খুলুন ডাটাবেস> Firestore ট্যাবে রুলস

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 নিয়ম পরিবর্তনশীল উপরে একটি বিশ্বব্যাপী পরিবর্তনশীল সব নিয়ম পাওয়া যায়, এবং শর্তাধীন আমরা যোগ নিশ্চিত করে যে অনুরোধ ব্যবহারকারীদের কিছু করতে অনুমতি দেওয়ার আগে প্রামাণ করা হয়। এটি অননুমোদিত ব্যবহারকারীদের আপনার ডেটাতে অননুমোদিত পরিবর্তন করতে Firestore API ব্যবহার করতে বাধা দেয়। এটি একটি ভাল শুরু, কিন্তু আমরা অনেক শক্তিশালী জিনিস করতে 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;
    }
  }
}

প্রথম ম্যাচে বিবৃতি subcollection নামে মিলে যায় ratings একাত্মতার যেকোন নথির restaurants সংগ্রহ। 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;
    }
  }
}

এখানে আমরা আমাদের লেখার অনুমতিকে তৈরি এবং আপডেটে বিভক্ত করেছি যাতে কোন অপারেশনের অনুমতি দেওয়া উচিত সে সম্পর্কে আমরা আরও সুনির্দিষ্ট হতে পারি। যে কোনো ব্যবহারকারী ডাটাবেসে রেস্তোরাঁ লিখতে পারে, কোডল্যাবের শুরুতে আমাদের তৈরি করা পপুলেট বোতামের কার্যকারিতা সংরক্ষণ করে, কিন্তু একবার কোনো রেস্তোরাঁর নাম লেখা হলে তার নাম, অবস্থান, মূল্য এবং বিভাগ পরিবর্তন করা যাবে না। আরো বিশেষভাবে, শেষ নিয়মের জন্য ডাটাবেসে ইতিমধ্যেই বিদ্যমান ক্ষেত্রগুলির একই নাম, শহর, মূল্য এবং বিভাগ বজায় রাখার জন্য কোন রেস্তোরাঁ আপডেট অপারেশন প্রয়োজন।

আপনি নিরাপত্তা নিয়ম কি করতে পারি সে সম্পর্কে আরো জানতে, কটাক্ষপাত করা ডকুমেন্টেশন

এই কোডল্যাবে, আপনি শিখলেন কিভাবে ফায়ারস্টোরের সাথে মৌলিক এবং উন্নত পড়া এবং লিখতে হয়, সেইসাথে কিভাবে নিরাপত্তা বিধি দিয়ে ডেটা অ্যাক্সেস সুরক্ষিত করতে হয়। আপনি পূর্ণ সমাধান জানতে পারেন codelab-complete শাখা

ফায়ারস্টোর সম্পর্কে আরও জানতে, নিম্নলিখিত সংস্থানগুলি দেখুন: