Google is committed to advancing racial equity for Black communities. See how.
หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

Cloud Firestore iOS Codelab

เป้าหมาย

ในโค้ดแล็บนี้คุณจะสร้างแอพแนะนำร้านอาหารที่ได้รับการสนับสนุนจาก Firestore บน iOS ใน Swift คุณจะได้เรียนรู้วิธีการ:

  1. อ่านและเขียนข้อมูลไปยัง Firestore จากแอป iOS
  2. ฟังการเปลี่ยนแปลงข้อมูล Firestore แบบเรียลไทม์
  3. ใช้ Firebase Authentication และกฎความปลอดภัยเพื่อรักษาความปลอดภัยข้อมูล Firestore
  4. เขียนแบบสอบถาม Firestore ที่ซับซ้อน

ข้อกำหนดเบื้องต้น

ก่อนเริ่ม codelab นี้ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง:

  • Xcode เวอร์ชัน 8.3 (หรือสูงกว่า)
  • CocoaPods 1.2.1 (หรือสูงกว่า)

เพิ่ม Firebase ในโปรเจ็กต์

  1. ไปที่ คอนโซล Firebase
  2. เลือก สร้างโครงการใหม่ และตั้งชื่อโครงการของคุณว่า "Firestore iOS Codelab"

ดาวน์โหลดรหัส

เริ่มต้นด้วยการโคลน โปรเจ็กต์ตัวอย่าง และรันการ pod update ในไดเร็กทอรีโปรเจ็กต์:

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

เปิด FriendlyEats.xcworkspace ใน Xcode และเรียกใช้ (Cmd + R) แอปควรคอมไพล์อย่างถูกต้องและหยุดทำงานทันทีเมื่อเปิดตัวเนื่องจากไม่มีไฟล์ GoogleService-Info.plist เราจะแก้ไขในขั้นตอนต่อไป

ตั้งค่า Firebase

ทำตาม เอกสาร เพื่อสร้างโปรเจ็กต์ Firestore ใหม่ เมื่อคุณมีโปรเจ็กต์แล้วให้ดาวน์โหลดไฟล์ GoogleService-Info.plist ของโปรเจ็ก GoogleService-Info.plist จาก คอนโซล Firebase แล้วลากไปที่รูทของโปรเจ็กต์ Xcode รันโปรเจ็กต์อีกครั้งเพื่อให้แน่ใจว่าแอพกำหนดค่าอย่างถูกต้องและไม่ขัดข้องเมื่อเปิดตัวอีกต่อไป หลังจากเข้าสู่ระบบคุณจะเห็นหน้าจอว่างเปล่าดังตัวอย่างด้านล่าง หากคุณไม่สามารถเข้าสู่ระบบได้โปรดตรวจสอบว่าคุณได้เปิดใช้งานวิธีการลงชื่อเข้าใช้อีเมล / รหัสผ่านในคอนโซล Firebase ภายใต้การตรวจสอบสิทธิ์

10a0671ce8f99704.png

ในส่วนนี้เราจะเขียนข้อมูลบางส่วนไปยัง Firestore เพื่อให้เราสามารถเติม UI ของแอปได้ ซึ่งสามารถทำได้ด้วยตนเองผ่าน คอนโซล 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 และอธิบายว่าส่วนใดของฐานข้อมูลของเราที่ผู้ใช้ควรเขียนได้ ในตอนนี้เราจะอนุญาตให้เฉพาะผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์เท่านั้นที่อ่านและเขียนไปยังฐานข้อมูลทั้งหมด สิ่งนี้อนุญาตเกินไปสำหรับแอปที่ใช้งานจริง แต่ในระหว่างขั้นตอนการสร้างแอปเราต้องการบางสิ่งที่ผ่อนคลายเพียงพอดังนั้นเราจะไม่พบปัญหาในการตรวจสอบสิทธิ์ตลอดเวลาขณะทดลอง ในตอนท้ายของ codelab นี้เราจะพูดถึงวิธีการทำให้กฎความปลอดภัยของคุณแข็งขึ้นและจำกัดความเป็นไปได้ในการอ่านและเขียนโดยไม่ได้ตั้งใจ

ใน แท็บกฎ ของคอนโซล 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 น. png

ขอแสดงความยินดีคุณเพิ่งเขียนข้อมูลไปยัง Firestore จากแอป iOS! ในส่วนถัดไปคุณจะได้เรียนรู้วิธีดึงข้อมูลจาก Firestore และแสดงในแอป

ในส่วนนี้คุณจะได้เรียนรู้วิธีดึงข้อมูลจาก Firestore และแสดงในแอป ขั้นตอนสำคัญสองขั้นตอนคือการสร้างแบบสอบถามและเพิ่มตัวฟังสแน็ปช็อต ผู้ฟังนี้จะได้รับแจ้งข้อมูลที่มีอยู่ทั้งหมดที่ตรงกับข้อความค้นหาและรับการอัปเดตแบบเรียลไทม์

ก่อนอื่นให้สร้างคำค้นหาที่จะแสดงรายการร้านอาหารเริ่มต้นที่ไม่มีการกรอง ดูการใช้งาน RestaurantsTableViewController.baseQuery() :

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

คำค้นหานี้ดึงข้อมูลร้านอาหารระดับบนสุดที่มีชื่อว่า "ร้านอาหาร" ได้มากถึง 50 ร้าน ตอนนี้เรามีคำถามแล้วเราต้องแนบ snapshot listener เพื่อโหลดข้อมูลจาก Firestore ลงในแอพของเรา เพิ่มรหัสต่อไปนี้ในเมธอด 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()
}

โค้ดด้านบนดาวน์โหลดคอลเล็กชันจาก Firestore และจัดเก็บไว้ในอาร์เรย์ภายในเครื่อง การ 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:) ของแหล่งข้อมูลมุมมองตารางซึ่งดูแลการแมปคอลเล็กชันประเภทค่าจากก่อนหน้าไปยังเซลล์มุมมองตารางแต่ละเซลล์

เรียกใช้แอปอีกครั้งและตรวจสอบว่าร้านอาหารที่เราเห็นก่อนหน้านี้ในคอนโซลสามารถมองเห็นได้บนเครื่องจำลองหรืออุปกรณ์ หากคุณทำส่วนนี้สำเร็จแอปของคุณกำลังอ่านและเขียนข้อมูลด้วย Cloud Firestore!

2ca7f8c6052f7f79.png

ขณะนี้แอปของเราแสดงรายชื่อร้านอาหาร แต่ไม่มีวิธีใดที่ผู้ใช้จะกรองตามความต้องการได้ ในส่วนนี้คุณจะใช้การสืบค้นขั้นสูงของ Firestore เพื่อเปิดใช้งานการกรอง

นี่คือตัวอย่างคำถามง่ายๆในการดึงข้อมูลร้านติ่มซำทั้งหมด:

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

ตามความหมายของชื่อ whereField(_:isEqualTo:) จะทำให้แบบสอบถามของเราดาวน์โหลดเฉพาะสมาชิกของคอลเล็กชันที่มีฟิลด์ตรงตามข้อ จำกัด ที่เราตั้งไว้ ในกรณีนี้จะดาวน์โหลดเฉพาะร้านอาหารที่ category คือ "Dim Sum"

ในแอปนี้ผู้ใช้สามารถเชื่อมโยงตัวกรองหลายตัวเพื่อสร้างข้อความค้นหาเฉพาะเช่น "Pizza in San Francisco" หรือ "Seafood in Los Angeles order by Popularity"

เปิด 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 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=...}

เนื่องจาก Firestore ต้องการดัชนีสำหรับการสืบค้นแบบผสมส่วนใหญ่ การกำหนดดัชนีในการสืบค้นช่วยให้ Firestore รวดเร็วในระดับ การเปิดลิงก์จากข้อความแสดงข้อผิดพลาดจะเปิด UI การสร้างดัชนีในคอนโซล Firebase โดยอัตโนมัติพร้อมด้วยพารามิเตอร์ที่ถูกต้องหากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับดัชนีใน Firestore โปรดไปที่เอกสาร

ในส่วนนี้เราจะเพิ่มความสามารถสำหรับผู้ใช้ในการส่งรีวิวร้านอาหาร จนถึงตอนนี้งานเขียนทั้งหมดของเราเป็นแบบปรมาณูและค่อนข้างเรียบง่าย หากมีข้อผิดพลาดใด ๆ เราอาจเพียงแจ้งให้ผู้ใช้ลองอีกครั้งหรือลองใหม่โดยอัตโนมัติ

ในการเพิ่มคะแนนให้กับร้านอาหารเราจำเป็นต้องประสานการอ่านและการเขียนหลาย ๆ ก่อนอื่นต้องส่งบทวิจารณ์จากนั้นจึงต้องอัปเดตจำนวนคะแนนของร้านอาหารและคะแนนเฉลี่ย หากข้อใดข้อหนึ่งล้มเหลว แต่ไม่เป็นเช่นนั้นเราจะอยู่ในสถานะที่ไม่สอดคล้องกันซึ่งข้อมูลในส่วนหนึ่งของฐานข้อมูลของเราไม่ตรงกับข้อมูลในอีกส่วนหนึ่ง

โชคดีที่ Firestore มีฟังก์ชันการทำธุรกรรมที่ช่วยให้เราสามารถอ่านและเขียนได้หลายรายการในการดำเนินการแบบปรมาณูเดียวเพื่อให้แน่ใจว่าข้อมูลของเรายังคงสอดคล้องกัน

เพิ่มรหัสต่อไปนี้ด้านล่างการประกาศ let ทั้งหมดใน 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 หากการอัปเดตล้มเหลวบนเซิร์ฟเวอร์ Firestore จะลองอีกครั้งโดยอัตโนมัติสองสามครั้ง ซึ่งหมายความว่าเงื่อนไขข้อผิดพลาดของเรามักจะเป็นข้อผิดพลาดเดียวที่เกิดขึ้นซ้ำ ๆ เช่นหากอุปกรณ์ออฟไลน์โดยสมบูรณ์หรือผู้ใช้ไม่ได้รับอนุญาตให้เขียนเส้นทางที่พวกเขาพยายามเขียนถึง

ผู้ใช้แอปของเราไม่ควรอ่านและเขียนข้อมูลทุกชิ้นในฐานข้อมูลของเรา ตัวอย่างเช่นทุกคนควรจะเห็นการให้คะแนนของร้านอาหาร แต่ควรอนุญาตให้เฉพาะผู้ใช้ที่ได้รับการรับรองเท่านั้นที่จะโพสต์คะแนนได้ ไม่เพียงพอที่จะเขียนโค้ดที่ดีบนไคลเอนต์เราจำเป็นต้องระบุรูปแบบการรักษาความปลอดภัยข้อมูลของเราในแบ็กเอนด์เพื่อให้ปลอดภัยอย่างสมบูรณ์ ในส่วนนี้เราจะเรียนรู้วิธีใช้กฎความปลอดภัยของ Firebase เพื่อปกป้องข้อมูลของเรา

ก่อนอื่นมาดูกฎความปลอดภัยที่เราเขียนไว้ตอนเริ่มต้น codelab เปิดคอนโซล 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 เพื่อทำสิ่งที่มีประสิทธิภาพมากขึ้น

มา จำกัด การเขียนบทวิจารณ์เพื่อให้ ID ผู้ใช้ของบทวิจารณ์ต้องตรงกับ ID ของผู้ใช้ที่ได้รับการพิสูจน์ตัวตน วิธีนี้ช่วยให้มั่นใจได้ว่าผู้ใช้จะไม่สามารถปลอมตัวเป็นบุคคลอื่นและแสดงความเห็นที่หลอกลวงได้ แทนที่กฎความปลอดภัยของคุณด้วยสิ่งต่อไปนี้:

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

คำชี้แจงการจับคู่แรกตรงกับคอลเล็กชันย่อยที่มีชื่อ ratings ของเอกสารใด ๆ ที่เป็นของคอลเลกชัน restaurants จากนั้น allow write เงื่อนไขจะป้องกันไม่ให้ส่งบทวิจารณ์ใด ๆ หาก ID ผู้ใช้ของบทวิจารณ์ไม่ตรงกับของผู้ใช้ คำสั่งจับคู่ที่สองช่วยให้ผู้ใช้ที่ได้รับการรับรองความถูกต้องสามารถอ่านและเขียนร้านอาหารลงในฐานข้อมูลได้

สิ่งนี้ใช้ได้ดีกับบทวิจารณ์ของเราเนื่องจากเราใช้กฎความปลอดภัยเพื่อระบุอย่างชัดเจนถึงการรับประกันโดยปริยายที่เราเขียนไว้ในแอปของเราก่อนหน้านี้ - ผู้ใช้สามารถเขียนบทวิจารณ์ของตนเอง หากเราจะเพิ่มฟังก์ชันแก้ไขหรือลบบทวิจารณ์ชุดกฎเดียวกันนี้จะป้องกันไม่ให้ผู้ใช้แก้ไขหรือลบบทวิจารณ์ของผู้ใช้รายอื่นด้วย แต่กฎ 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;
    }
  }
}

ที่นี่เราได้แยกสิทธิ์ในการเขียนของเราออกเป็นสร้างและอัปเดตเพื่อให้เรามีความเฉพาะเจาะจงมากขึ้นเกี่ยวกับการดำเนินการที่ควรได้รับอนุญาต ผู้ใช้ทุกคนสามารถเขียนร้านอาหารลงในฐานข้อมูลโดยรักษาการทำงานของปุ่มเติมข้อมูลที่เราสร้างไว้ตอนเริ่มต้น codelab แต่เมื่อร้านอาหารเขียนชื่อสถานที่ราคาและหมวดหมู่แล้วไม่สามารถเปลี่ยนแปลง โดยเฉพาะอย่างยิ่งกฎสุดท้ายกำหนดให้มีการดำเนินการอัปเดตร้านอาหารเพื่อรักษาชื่อเมืองราคาและหมวดหมู่เดิมของช่องที่มีอยู่แล้วในฐานข้อมูล

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับสิ่งที่คุณสามารถทำได้กับกฎความปลอดภัยโปรดดู เอกสารประกอบ

ใน codelab นี้คุณได้เรียนรู้วิธีการอ่านและเขียนขั้นพื้นฐานและขั้นสูงด้วย Firestore ตลอดจนวิธีรักษาความปลอดภัยการเข้าถึงข้อมูลด้วยกฎความปลอดภัย คุณสามารถค้นหาโซลูชัน codelab-complete สาขาที่ codelab-complete ของ codelab-complete

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ Firestore โปรดไปที่แหล่งข้อมูลต่อไปนี้: