ทำงานกับรายการข้อมูลบนแพลตฟอร์ม Apple

รับ FIRDatabaseReference

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

สวิฟต์

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

ref = Database.database().reference()

วัตถุประสงค์-C

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

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

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

ผนวกเข้ากับรายการข้อมูล

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

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

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

ฟังเหตุการณ์เด็ก

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

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

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

สวิฟต์

หมายเหตุ: ผลิตภัณฑ์ 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
  )
})

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

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

สวิฟต์

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

วัตถุประสงค์-C

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

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

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

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

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

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

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

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

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

สวิฟต์

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

วัตถุประสงค์-C

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

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

การเรียกเมธอด 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 ของเรา

สวิฟต์

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

วัตถุประสงค์-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 คุณจะได้รับการโทรกลับ FIRDataEventTypeChildAdded สูงสุด 100 ครั้งเท่านั้น หากคุณมีรายการที่เก็บไว้ในฐานข้อมูล Firebase น้อยกว่า 100 รายการ การเรียกกลับ FIRDataEventTypeChildAdded จะเริ่มทำงานสำหรับแต่ละรายการ

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

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

สวิฟต์

หมายเหตุ: ผลิตภัณฑ์ 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))!

วัตถุประสงค์-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. ออบเจกต์จะอยู่หลังสุดและจัดเรียงตามพจนานุกรมตามคีย์ในลำดับจากน้อยไปหามาก

แยกผู้ฟัง

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

เมื่อคุณเพิ่มบล็อกการโทรกลับในการอ้างอิง FIRDatabaseHandle จะถูกส่งกลับ หมายเลขอ้างอิงเหล่านี้สามารถใช้เพื่อลบบล็อกการโทรกลับ

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

การเรียก removeObserverWithHandle หรือ removeAllObservers บนผู้ฟังไม่ได้ลบผู้ฟังที่ลงทะเบียนบนโหนดย่อยโดยอัตโนมัติ คุณต้องติดตามการอ้างอิงหรือหมายเลขอ้างอิงเหล่านั้นเพื่อลบออก

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