รับ `FIRDatabaseReference`
หากต้องการอ่านหรือเขียนข้อมูลจากฐานข้อมูล คุณต้องมีอินสแตนซ์ของ FIRDatabaseReference
Swift
var ref: DatabaseReference! ref = Database.database().reference()
Objective-C
@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
// 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
// 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
_commentsRef.observe(.value) { snapshot in for child in snapshot.children { ... } }
Objective-C
[_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
// My top posts by number of stars let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")
Objective-C
// 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
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")
Objective-C
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
// 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
// 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 เพื่อจัดเรียงข้อมูล ระบบจะแสดงผลข้อมูลตามลำดับจากน้อยไปมากตามคีย์
- รายการย่อยที่มีคีย์ที่แยกวิเคราะห์เป็นจำนวนเต็ม 32 บิตได้จะแสดงก่อน โดยจัดเรียงตามลำดับจากน้อยไปมาก
- รายการย่อยที่มีค่าสตริงเป็นคีย์จะแสดงถัดมา โดยจัดเรียงตามลำดับพจนานุกรมจากน้อยไปมาก
queryOrderedByValue
เมื่อใช้ queryOrderedByValue ระบบจะจัดเรียงรายการย่อยตามค่า เกณฑ์การจัดเรียงจะเหมือนกับใน queryOrderedByChild ยกเว้นว่าจะใช้ค่าของโหนดแทนค่าของคีย์ของรายการย่อยที่ระบุ
queryOrderedByChild
เมื่อใช้ queryOrderedByChild ระบบจะจัดเรียงข้อมูลที่มีคีย์ของรายการย่อยที่ระบุดังนี้
- รายการย่อยที่มีค่า
nilสำหรับคีย์ของรายการย่อยที่ระบุจะแสดง ก่อน - รายการย่อยที่มีค่า
falseสำหรับคีย์ของรายการย่อยที่ระบุ จะแสดงถัดมา หากรายการย่อยหลายรายการมีค่าfalseระบบจะจัดเรียงรายการเหล่านั้นตามลำดับพจนานุกรมตามคีย์ - รายการย่อยที่มีค่า
trueสำหรับคีย์ของรายการย่อยที่ระบุ จะแสดงถัดมา หากรายการย่อยหลายรายการมีค่าtrueระบบจะจัดเรียงรายการเหล่านั้นตามลำดับพจนานุกรมตามคีย์ - รายการย่อยที่มีค่าตัวเลขจะแสดงถัดมา โดยจัดเรียงตามลำดับจากน้อยไปมาก หากรายการย่อยหลายรายการมีค่าตัวเลขเดียวกันสำหรับโหนดรายการย่อยที่ระบุ ระบบจะจัดเรียงรายการเหล่านั้นตามคีย์
- สตริงจะแสดงหลังตัวเลขและจัดเรียงตามลำดับพจนานุกรมจากน้อยไปมาก หากรายการย่อยหลายรายการมีค่าเดียวกันสำหรับโหนดรายการย่อยที่ระบุ ระบบจะจัดเรียงรายการเหล่านั้นตามลำดับพจนานุกรมตามคีย์
- ออบเจ็กต์จะแสดงสุดท้ายและจัดเรียงตามลำดับพจนานุกรมตามคีย์จากน้อยไปมาก
ยกเลิกการแนบ Listener
Observer จะไม่หยุดซิงค์ข้อมูลโดยอัตโนมัติเมื่อคุณออกจาก ViewController หากไม่ได้นำ Observer ออกอย่างถูกต้อง Observer จะซิงค์ข้อมูลกับหน่วยความจำภายในเครื่องต่อไปและจะเก็บออบเจ็กต์ที่บันทึกไว้ใน Closure ของตัวแฮนเดิลเหตุการณ์ ซึ่งอาจทำให้เกิดหน่วยความจำรั่ว เมื่อไม่ต้องการ Observer อีกต่อไป ให้นำ Observer ออกโดยส่ง FIRDatabaseHandle ที่เชื่อมโยงไปยังเมธอด removeObserverWithHandle
เมื่อคุณเพิ่มบล็อก Callback ลงในการอ้างอิง ระบบจะแสดงผล FIRDatabaseHandle
คุณสามารถใช้แฮนเดิลเหล่านี้เพื่อนำบล็อก Callback ออกได้
หากมีการเพิ่ม Listener หลายรายการลงในการอ้างอิงฐานข้อมูล ระบบจะเรียก Listener แต่ละรายการเมื่อมีการทริกเกอร์เหตุการณ์ หากต้องการหยุดซิงค์ข้อมูลในตำแหน่งนั้น คุณต้องนำ Observer ทั้งหมดในตำแหน่งนั้นออกโดยเรียกเมธอด removeAllObservers
การเรียก removeObserverWithHandle หรือ removeAllObservers ใน Listener จะไม่นำ Listener ที่ลงทะเบียนไว้ในโหนดรายการย่อยออกโดยอัตโนมัติ คุณต้องติดตามการอ้างอิงหรือแฮนเดิลเหล่านั้นเพื่อนำออกด้วย