ใช้งานรายการข้อมูลในแพลตฟอร์ม Apple

รับ FIRDatabaseReference

หากต้องการอ่านหรือเขียนข้อมูลจากฐานข้อมูล คุณต้องมีอินสแตนซ์ของ FIRDatabaseReference ดังนี้

Swift

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
var ref: DatabaseReference!

ref = Database.database().reference()

Objective-C

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ไม่พร้อมใช้งานในเป้าหมาย App Clip
@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];

การอ่านและการเขียนรายการ

เพิ่มต่อท้ายรายการข้อมูล

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

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

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

รอรับเหตุการณ์ย่อย

ระบบจะทริกเกอร์เหตุการณ์ย่อยเพื่อตอบสนองต่อการดำเนินการที่เฉพาะเจาะจงซึ่งเกิดขึ้นกับโหนดย่อยจากการดำเนินการ เช่น โหนดย่อยใหม่ที่เพิ่มผ่านเมธอด childByAutoId หรือโหนดย่อยที่อัปเดตผ่านเมธอด updateChildValues

ประเภทเหตุการณ์ การใช้งานทั่วไป
FIRDataEventTypeChildAdded เรียกดูรายการสิ่งของหรือฟังการเพิ่มสิ่งของลงในรายการ เหตุการณ์นี้จะทริกเกอร์ 1 ครั้งสำหรับโหนดลูกที่มีอยู่แต่ละโหนด และจะทริกเกอร์อีกครั้งทุกครั้งที่มีการเพิ่มโหนดลูกใหม่ลงในเส้นทางที่ระบุ ระบบจะส่งภาพรวมที่มีข้อมูลของรายการย่อยใหม่ไปยัง Listener
FIRDataEventTypeChildChanged ฟังการเปลี่ยนแปลงของรายการในลิสต์ เหตุการณ์นี้จะทริกเกอร์ทุกครั้งที่มีการแก้ไขโหนดย่อย ซึ่งรวมถึงการแก้ไขโหนดสืบทอดของโหนดย่อย สแนปชอตที่ส่งไปยัง Listener เหตุการณ์จะมีข้อมูลที่อัปเดตสำหรับรายการย่อย
FIRDataEventTypeChildRemoved ฟังรายการที่ถูกนำออกจากลิสต์ เหตุการณ์นี้จะทริกเกอร์เมื่อมีการนำรายการย่อยที่อยู่ติดกันออก สแนปชอตที่ส่งไปยังบล็อก Callback จะมีข้อมูลของรายการย่อยที่นำออก
FIRDataEventTypeChildMoved ฟังการเปลี่ยนแปลงลำดับของรายการในรายการตามลำดับ เหตุการณ์นี้จะทริกเกอร์เมื่อใดก็ตามที่การอัปเดตทำให้เกิดการจัดเรียงรายการย่อยใหม่ โดยจะใช้กับข้อมูลที่จัดเรียงตาม queryOrderedByChild หรือ queryOrderedByValue

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

Swift

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
// Listen for new comments in the Firebase database
commentsRef.observe(.childAdded, with: { (snapshot) -> Void in
  self.comments.append(snapshot)
  self.tableView.insertRows(
    at: [IndexPath(row: self.comments.count - 1, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})
// Listen for deleted comments in the Firebase database
commentsRef.observe(.childRemoved, with: { (snapshot) -> Void in
  let index = self.indexOfMessage(snapshot)
  self.comments.remove(at: index)
  self.tableView.deleteRows(
    at: [IndexPath(row: index, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})

Objective-C

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
// Listen for new comments in the Firebase database
[_commentsRef
              observeEventType:FIRDataEventTypeChildAdded
              withBlock:^(FIRDataSnapshot *snapshot) {
                [self.comments addObject:snapshot];
                [self.tableView insertRowsAtIndexPaths:@[
                  [NSIndexPath indexPathForRow:self.comments.count - 1 inSection:kSectionComments]
                ]
                                      withRowAnimation:UITableViewRowAnimationAutomatic];
              }];
// Listen for deleted comments in the Firebase database
[_commentsRef
 observeEventType:FIRDataEventTypeChildRemoved
 withBlock:^(FIRDataSnapshot *snapshot) {
   int index = [self indexOfMessage:snapshot];
   [self.comments removeObjectAtIndex:index];
   [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:kSectionComments]]
                         withRowAnimation:UITableViewRowAnimationAutomatic];
 }];

ฟังเหตุการณ์ค่า

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

การแนบ FIRDataEventTypeValue Observer กับรายการข้อมูลจะแสดงรายการข้อมูลทั้งหมดเป็น DataSnapshot รายการเดียว ซึ่งคุณสามารถวนซ้ำเพื่อเข้าถึงรายการย่อยแต่ละรายการได้

แม้ว่าจะมีรายการที่ตรงกันเพียงรายการเดียวสำหรับคำค้นหา แต่ภาพรวมก็ยังคงเป็นรายการที่มีเพียงรายการเดียว หากต้องการเข้าถึงรายการ คุณต้องวนซ้ำผลลัพธ์ดังนี้

Swift

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

Objective-C

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
[_commentsRef
              observeEventType:FIRDataEventTypeValue
              withBlock:^(FIRDataSnapshot *snapshot) {
                // Loop over children
                NSEnumerator *children = [snapshot children];
                FIRDataSnapshot *child;
                while (child = [children nextObject]) {
                  // ...
                }
              }];

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

การจัดเรียงและการกรองข้อมูล

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

จัดเรียงข้อมูล

หากต้องการดึงข้อมูลที่จัดเรียงแล้ว ให้เริ่มด้วยการระบุเมธอดการจัดเรียงลำดับวิธีใดวิธีหนึ่งเพื่อกำหนดวิธีจัดเรียงผลลัพธ์ ดังนี้

วิธีการ การใช้งาน
queryOrderedByKey จัดเรียงผลลัพธ์ตามคีย์ย่อย
queryOrderedByValue จัดเรียงผลลัพธ์ตามค่าของรายการย่อย
queryOrderedByChild จัดเรียงผลลัพธ์ตามค่าของคีย์ย่อยที่ระบุหรือเส้นทางย่อยที่ฝังอยู่

คุณใช้เมธอดการจัดเรียงลำดับได้ครั้งละ 1 เมธอดเท่านั้น การเรียกใช้เมธอดการจัดเรียงลำดับหลายครั้งในคำค้นหาเดียวกันจะทำให้เกิดข้อผิดพลาด

ตัวอย่างต่อไปนี้แสดงวิธีดึงข้อมูลรายการโพสต์ยอดนิยมของผู้ใช้ที่จัดเรียงตามจำนวนดาว

Swift

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
// My top posts by number of stars
let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")

Objective-C

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
// My top posts by number of stars
FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"]
                                      child:[super getUid]]
                                     queryOrderedByChild:@"starCount"];

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

การเรียกใช้เมธอด queryOrderedByChild จะระบุคีย์ย่อยเพื่อจัดเรียงผลลัพธ์ ในตัวอย่างนี้ โพสต์จะจัดเรียงตามค่าของรายการย่อย "starCount" ในแต่ละโพสต์ นอกจากนี้ คุณยังจัดเรียงการค้นหาตามรายการย่อยที่ซ้อนกันได้ในกรณีที่มีข้อมูลลักษณะนี้

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

ในกรณีนี้ เราสามารถจัดเรียงองค์ประกอบรายการตามค่าที่ฝังอยู่ใต้คีย์ metrics โดยระบุ Relative Path ไปยังรายการย่อยที่ฝังอยู่ในการเรียก queryOrderedByChild

Swift

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

Objective-C

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดเรียงข้อมูลประเภทอื่นๆ ได้ที่วิธีจัดเรียงข้อมูลการค้นหา

การกรองข้อมูล

หากต้องการกรองข้อมูล คุณสามารถรวมเมธอดขีดจำกัดหรือช่วงเข้ากับเมธอดการจัดเรียงลำดับเมื่อสร้างการค้นหา

วิธีการ การใช้งาน
queryLimitedToFirst กำหนดจำนวนรายการสูงสุดที่จะแสดงผลจากจุดเริ่มต้นของรายการผลลัพธ์ตามลำดับ
queryLimitedToLast กำหนดจำนวนรายการสูงสุดที่จะแสดงผลจากส่วนท้ายของรายการผลลัพธ์ที่จัดเรียงแล้ว
queryStartingAtValue แสดงผลรายการที่มากกว่าหรือเท่ากับคีย์หรือค่าที่ระบุ โดยขึ้นอยู่กับเมธอดการจัดเรียงลำดับที่เลือก
queryStartingAfterValue แสดงผลรายการที่มากกว่าคีย์หรือค่าที่ระบุ โดยขึ้นอยู่กับเมธอดการจัดเรียงลำดับที่เลือก
queryEndingAtValue แสดงผลรายการที่น้อยกว่าหรือเท่ากับคีย์หรือค่าที่ระบุ โดยขึ้นอยู่กับเมธอดการจัดเรียงลำดับที่เลือก
queryEndingBeforeValue แสดงผลรายการที่น้อยกว่าคีย์หรือค่าที่ระบุ โดยขึ้นอยู่กับเมธอดการจัดเรียงลำดับที่เลือก
queryEqualToValue แสดงผลรายการที่เท่ากับคีย์หรือค่าที่ระบุ โดยขึ้นอยู่กับเมธอดการจัดเรียงลำดับที่เลือก

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

จำกัดจำนวนผลลัพธ์

คุณสามารถใช้เมธอด queryLimitedToFirst และ queryLimitedToLast เพื่อกำหนดจำนวนสูงสุดของรายการย่อยที่จะซิงค์สำหรับการเรียกกลับที่ระบุ เช่น หากคุณใช้ queryLimitedToFirst เพื่อตั้งค่าขีดจำกัดเป็น 100 ในตอนแรกคุณจะได้รับ Callback ของ FIRDataEventTypeChildAdded สูงสุด 100 รายการเท่านั้น หากคุณมีรายการที่จัดเก็บไว้ในฐานข้อมูล Firebase น้อยกว่า 100 รายการ ระบบจะเรียกใช้ Callback FIRDataEventTypeChildAdded สำหรับแต่ละรายการ

เมื่อรายการเปลี่ยนแปลง คุณจะได้รับ Callback FIRDataEventTypeChildAdded รายการสำหรับรายการที่เข้าสู่การค้นหา และ Callback FIRDataEventTypeChildRemoved รายการสำหรับรายการที่ออกจากการค้นหา เพื่อให้จำนวนรวมยังคงอยู่ที่ 100 รายการ

ตัวอย่างต่อไปนี้แสดงวิธีที่แอปบล็อกตัวอย่างอาจดึงข้อมูลรายการโพสต์ล่าสุด 100 รายการจากผู้ใช้ทั้งหมด

Swift

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!

Objective-C

หมายเหตุ: ผลิตภัณฑ์ Firebase นี้ใช้ไม่ได้กับเป้าหมาย App Clip
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];

กรองตามคีย์หรือค่า

คุณสามารถใช้ queryStartingAtValue, queryStartingAfterValue, queryEndingAtValue, queryEndingBeforeValue และ queryEqualToValue เพื่อเลือกจุดเริ่มต้น จุดสิ้นสุด และจุดที่เทียบเท่ากันตามต้องการสำหรับการค้นหา ซึ่งจะเป็นประโยชน์สำหรับการแบ่งหน้าข้อมูลหรือค้นหารายการที่มีรายการย่อยซึ่งมีค่าที่เฉพาะเจาะจง

วิธีจัดเรียงข้อมูลการค้นหา

ส่วนนี้จะอธิบายวิธีจัดเรียงข้อมูลตามเมธอดการจัดเรียงลำดับแต่ละเมธอดในคลาส FIRDatabaseQuery

queryOrderedByKey

เมื่อใช้ queryOrderedByKey เพื่อจัดเรียงข้อมูล ระบบจะแสดงข้อมูลตามลำดับจากน้อยไปมากตามคีย์

  1. รายการย่อยที่มีคีย์ที่แยกวิเคราะห์เป็นจำนวนเต็ม 32 บิตได้จะแสดงก่อน โดยจัดเรียงตามลำดับจากน้อยไปมาก
  2. รายการย่อยที่มีค่าสตริงเป็นคีย์จะอยู่ถัดไป โดยจัดเรียงตามพจนานุกรมจากน้อยไปมาก

queryOrderedByValue

เมื่อใช้ queryOrderedByValue ระบบจะจัดเรียงองค์ประกอบย่อยตามค่าขององค์ประกอบ เกณฑ์การจัดลำดับจะเหมือนกับใน queryOrderedByChild ยกเว้นว่าจะใช้ค่าของโหนดแทนค่าของคีย์ย่อยที่ระบุ

queryOrderedByChild

เมื่อใช้ queryOrderedByChild ข้อมูลที่มีคีย์ย่อยที่ระบุจะจัดเรียงดังนี้

  1. รายการย่อยที่มีค่า nil สำหรับคีย์ย่อยที่ระบุจะแสดงก่อน
  2. ตามด้วยรายการย่อยที่มีค่า false สำหรับคีย์ย่อยที่ระบุ หากโหนดบุตรหลายโหนดมีค่าเป็น false ระบบจะจัดเรียงโหนดบุตรเหล่านั้นตามพจนานุกรมตามคีย์
  3. ตามด้วยรายการย่อยที่มีค่า true สำหรับคีย์ย่อยที่ระบุ หากโหนดบุตรหลายโหนดมีค่าเป็น true ระบบจะจัดเรียงตามพจนานุกรมตามคีย์
  4. ตามด้วยรายการย่อยที่มีค่าเป็นตัวเลข โดยจัดเรียงจากน้อยไปมาก หากโหนดย่อยหลายโหนดมีค่าตัวเลขเดียวกันสำหรับโหนดย่อยที่ระบุ ระบบจะจัดเรียงตามคีย์
  5. สตริงจะอยู่หลังตัวเลขและจัดเรียงตามพจนานุกรมจากน้อยไปมาก หากโหนดย่อยหลายโหนดมีค่าเดียวกันสำหรับโหนดย่อยที่ระบุ ระบบจะจัดเรียงตามพจนานุกรมตามคีย์
  6. ออบเจ็กต์จะอยู่ท้ายสุดและจัดเรียงตามพจนานุกรมตามคีย์จากน้อยไปมาก

แยก Listener

Observer จะไม่หยุดซิงค์ข้อมูลโดยอัตโนมัติเมื่อคุณออกจาก ViewController หากไม่ได้นำ Observer ออกอย่างถูกต้อง ระบบจะยังคงซิงค์ข้อมูลกับหน่วยความจำในเครื่องและเก็บออบเจ็กต์ที่บันทึกไว้ใน Closure ของตัวแฮนเดิลเหตุการณ์ ซึ่งอาจทำให้หน่วยความจำรั่วไหล เมื่อไม่จำเป็นต้องใช้ Observer อีกต่อไป ให้นำออกโดยส่ง FIRDatabaseHandle ที่เชื่อมโยงไปยังเมธอด removeObserverWithHandle

เมื่อคุณเพิ่มบล็อก Callback ลงในการอ้างอิง ระบบจะแสดงผล FIRDatabaseHandle แฮนเดิลเหล่านี้ใช้เพื่อนำบล็อก Callback ออกได้

หากมีการเพิ่ม Listener หลายรายการในการอ้างอิงฐานข้อมูล ระบบจะเรียกใช้ Listener แต่ละรายการเมื่อมีเหตุการณ์เกิดขึ้น หากต้องการหยุดซิงค์ข้อมูลที่ตำแหน่งนั้น คุณต้องนำผู้สังเกตการณ์ทั้งหมดที่ตำแหน่งออกโดยเรียกใช้เมธอด removeAllObservers

การเรียก removeObserverWithHandle หรือ removeAllObservers ใน Listener จะไม่นำ Listener ที่ลงทะเบียนไว้ในโหนดบุตรหลานออกโดยอัตโนมัติ คุณต้องติดตามการอ้างอิงหรือแฮนเดิลเหล่านั้นเพื่อนำออกด้วย

ขั้นตอนถัดไป