ใช้งานรายการข้อมูลในแพลตฟอร์ม 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];
 }];

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

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

การแนบ Observer FIRDataEventTypeValue กับรายการข้อมูลจะแสดงผลรายการข้อมูลทั้งหมดเป็น 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 เพื่อดึงข้อมูลที่จัดเรียง ตามคีย์ ตามค่า หรือตามค่าของรายการย่อย นอกจากนี้ คุณยังกรองผลการค้นหาที่จัดเรียงแล้วให้แสดงผลลัพธ์ตามจำนวนที่เฉพาะเจาะจงหรือตามช่วงคีย์หรือค่าได้ด้วย

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

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

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

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

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

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 ได้โดยการระบุเส้นทางสัมพัทธ์ไปยังรายการย่อยแบบซ้อนในการเรียก 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"];

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

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

หากต้องการกรองข้อมูล คุณสามารถรวมเมธอด limit หรือ range ใดก็ได้กับเมธอด order-by เมื่อสร้างการค้นหา

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

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

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

คุณสามารถใช้เมธอด queryLimitedToFirst และ queryLimitedToLast เพื่อกำหนดจำนวนสูงสุดของรายการย่อยที่จะซิงค์สำหรับ Callback ที่กำหนด ตัวอย่างเช่น หากคุณใช้ 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 เพื่อเลือกจุดเริ่มต้น จุดสิ้นสุด และจุดเทียบเท่าที่กำหนดเองสำหรับการค้นหา ซึ่งอาจมีประโยชน์สำหรับการแบ่งหน้าข้อมูลหรือการค้นหารายการที่มีรายการย่อยที่มีค่าที่เฉพาะเจาะจง

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

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

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

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

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

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