ก่อนเริ่มต้น
คุณต้องดำเนินการต่อไปนี้ก่อนจึงจะใช้ Realtime Database, ได้
ลงทะเบียนโปรเจ็กต์ Unity และกำหนดค่าให้ใช้ Firebase
หากโปรเจ็กต์ Unity ใช้ Firebase อยู่แล้ว แสดงว่าโปรเจ็กต์ได้ลงทะเบียนและกำหนดค่าสำหรับ Firebase แล้ว
หากไม่มีโปรเจ็กต์ Unity คุณสามารถดาวน์โหลด แอปตัวอย่างได้
เพิ่ม Firebase Unity SDK (โดยเฉพาะ
FirebaseDatabase.unitypackage) ลงใน โปรเจ็กต์ Unity
โปรดทราบว่าการเพิ่ม Firebase ลงในโปรเจ็กต์ Unity เกี่ยวข้องกับงานทั้งใน Firebaseคอนโซลและในโปรเจ็กต์ Unity ที่เปิดอยู่ (เช่น คุณดาวน์โหลดไฟล์การกำหนดค่า Firebase จากคอนโซล แล้วย้าย ไฟล์เหล่านั้นไปยังโปรเจ็กต์ Unity)
การจัดโครงสร้างข้อมูล
คู่มือนี้ครอบคลุมแนวคิดหลักบางประการในสถาปัตยกรรมข้อมูลและแนวทางปฏิบัติแนะนำสำหรับการจัดโครงสร้างข้อมูล JSON ใน Firebase Realtime Database
การสร้างฐานข้อมูลที่มีโครงสร้างอย่างเหมาะสมต้องมีการวางแผนล่วงหน้าพอสมควร สิ่งที่สำคัญที่สุดคือคุณต้องวางแผนวิธีบันทึกและดึงข้อมูลในภายหลังเพื่อให้กระบวนการดังกล่าวเป็นไปได้ง่ายที่สุด
วิธีจัดโครงสร้างข้อมูล: เป็นแผนผัง JSON
ระบบจะจัดเก็บข้อมูลทั้งหมดของ Firebase Realtime Database เป็นออบเจ็กต์ JSON คุณสามารถนึกภาพฐานข้อมูลเป็นแผนผัง JSON ที่โฮสต์บนระบบคลาวด์ ซึ่งแตกต่างจากฐานข้อมูล SQL ที่ไม่มีตารางหรือระเบียน เมื่อคุณเพิ่มข้อมูลลงในแผนผัง JSON ข้อมูลนั้นจะกลายเป็นโหนดในโครงสร้าง JSON ที่มีอยู่พร้อมคีย์ที่เชื่อมโยง คุณสามารถระบุคีย์ของคุณเอง เช่น รหัสผู้ใช้หรือชื่อเชิงความหมาย หรือระบบจะระบุคีย์ให้คุณโดยใช้วิธี Push()
ตัวอย่างเช่น ลองพิจารณาแอปพลิเคชันแชทที่อนุญาตให้ผู้ใช้จัดเก็บโปรไฟล์พื้นฐานและข้อมูลรายชื่อติดต่อ โปรไฟล์ผู้ใช้ทั่วไปจะอยู่ในเส้นทาง เช่น /users/$uid ผู้ใช้ alovelace อาจมีรายการฐานข้อมูลลักษณะดังนี้
{ "users": { "alovelace": { "name": "Ada Lovelace", "contacts": { "ghopper": true }, }, "ghopper": { "..." }, "eclarke": { "..." } } }
แม้ว่าฐานข้อมูลจะใช้แผนผัง JSON แต่ข้อมูลที่จัดเก็บไว้ในฐานข้อมูลสามารถแสดงเป็นประเภทข้อมูลดั้งเดิมบางประเภทที่สอดคล้องกับประเภท JSON ที่มีอยู่เพื่อช่วยให้คุณเขียนโค้ดที่ดูแลรักษาง่ายขึ้น
แนวทางปฏิบัติแนะนำสำหรับโครงสร้างข้อมูล
หลีกเลี่ยงการซ้อนข้อมูล
เนื่องจาก Firebase Realtime Database อนุญาตให้ซ้อนข้อมูลได้ลึกถึง 32 ระดับ คุณจึงอาจคิดว่านี่ควรเป็นโครงสร้างเริ่มต้น อย่างไรก็ตาม เมื่อคุณดึงข้อมูลที่ตำแหน่งหนึ่งในฐานข้อมูล คุณจะดึงโหนดลูกทั้งหมดของข้อมูลนั้นด้วย นอกจากนี้ เมื่อคุณให้สิทธิ์เข้าถึงแบบอ่านหรือเขียนแก่บุคคลอื่นที่โหนดหนึ่งในฐานข้อมูล คุณยังให้สิทธิ์เข้าถึงข้อมูลทั้งหมดภายใต้โหนดนั้นด้วย ดังนั้น ในทางปฏิบัติ วิธีที่ดีที่สุดคือการทำให้โครงสร้างข้อมูลแบนราบมากที่สุด
ตัวอย่างเหตุผลที่การซ้อนข้อมูลไม่ดี ให้พิจารณาโครงสร้างที่ซ้อนกันหลายชั้นต่อไปนี้
{ // This is a poorly nested data architecture, because iterating the children // of the "chats" node to get a list of conversation titles requires // potentially downloading hundreds of megabytes of messages "chats": { "one": { "title": "Historical Tech Pioneers", "messages": { "m1": { "sender": "ghopper", "message": "Relay malfunction found. Cause: moth." }, "m2": { ... }, // a very long list of messages } }, "two": { "..." } } }
การออกแบบที่ซ้อนกันนี้ทำให้การวนซ้ำข้อมูลกลายเป็นปัญหา ตัวอย่างเช่น การแสดงรายการชื่อของการสนทนาแชทต้องดาวน์โหลดแผนผัง chats ทั้งหมด รวมถึงสมาชิกและข้อความทั้งหมดลงในไคลเอ็นต์
ทำให้โครงสร้างข้อมูลแบนราบ
หากแยกข้อมูลออกเป็นเส้นทางที่แยกกัน หรือที่เรียกว่าการยกเลิกการทำให้เป็นปกติ ระบบจะดาวน์โหลดข้อมูลได้อย่างมีประสิทธิภาพในการเรียกที่แยกกันตามความจำเป็น ลองพิจารณาโครงสร้างที่แบนราบต่อไปนี้
{ // Chats contains only meta info about each conversation // stored under the chats's unique ID "chats": { "one": { "title": "Historical Tech Pioneers", "lastMessage": "ghopper: Relay malfunction found. Cause: moth.", "timestamp": 1459361875666 }, "two": { "..." }, "three": { "..." } }, // Conversation members are easily accessible // and stored by chat conversation ID "members": { // we'll talk about indices like this below "one": { "ghopper": true, "alovelace": true, "eclarke": true }, "two": { "..." }, "three": { "..." } }, // Messages are separate from data we may want to iterate quickly // but still easily paginated and queried, and organized by chat // conversation ID "messages": { "one": { "m1": { "name": "eclarke", "message": "The relay seems to be malfunctioning.", "timestamp": 1459361875337 }, "m2": { "..." }, "m3": { "..." } }, "two": { "..." }, "three": { "..." } } }
ตอนนี้คุณสามารถวนซ้ำรายการห้องแชทได้โดยการดาวน์โหลดข้อมูลเพียงไม่กี่ไบต์ต่อการสนทนา ซึ่งจะดึงข้อมูลเมตาอย่างรวดเร็วสำหรับการแสดงรายการหรือแสดงห้องแชทใน UI ระบบจะดึงข้อความแยกกันและแสดงเมื่อข้อความมาถึง ซึ่งช่วยให้ UI ตอบสนองและทำงานได้อย่างรวดเร็ว
สร้างข้อมูลที่ปรับขนาดได้
เมื่อสร้างแอป การดาวน์โหลดชุดย่อยของรายการมักจะเป็นวิธีที่ดีกว่า วิธีนี้เป็นวิธีที่ใช้กันโดยทั่วไปหากรายการมีระเบียนหลายพันรายการ เมื่อความสัมพันธ์นี้คงที่และเป็นแบบทางเดียว คุณสามารถซ้อนออบเจ็กต์ลูกไว้ใต้ออบเจ็กต์แม่ได้
บางครั้งความสัมพันธ์นี้อาจมีความเปลี่ยนแปลงมากขึ้น หรืออาจจำเป็นต้องยกเลิกการทำให้ข้อมูลนี้เป็นปกติ หลายครั้งที่คุณสามารถยกเลิกการทำให้ข้อมูลเป็นปกติได้โดยใช้การค้นหา เพื่อดึงข้อมูลชุดย่อย ดังที่อธิบายไว้ใน ดึงข้อมูล
แต่แม้แต่วิธีนี้ก็อาจไม่เพียงพอ ตัวอย่างเช่น ลองพิจารณาความสัมพันธ์แบบ 2 ทางระหว่างผู้ใช้กับกลุ่ม ผู้ใช้สามารถอยู่ในกลุ่มได้ และกลุ่มประกอบด้วยรายชื่อผู้ใช้ เมื่อถึงเวลาตัดสินใจว่าผู้ใช้รายใดอยู่ในกลุ่มใด สิ่งต่างๆ จะซับซ้อนขึ้น
สิ่งที่คุณต้องการคือวิธีที่สวยงามในการแสดงรายการกลุ่มที่ผู้ใช้เป็นสมาชิกและดึงเฉพาะข้อมูลของกลุ่มเหล่านั้น ดัชนีของกลุ่มช่วยได้มากในที่นี้
// An index to track Ada's memberships { "users": { "alovelace": { "name": "Ada Lovelace", // Index Ada's groups in her profile "groups": { // the value here doesn't matter, just that the key exists "techpioneers": true, "womentechmakers": true } }, // ... }, "groups": { "techpioneers": { "name": "Historical Tech Pioneers", "members": { "alovelace": true, "ghopper": true, "eclarke": true } }, // ... } }
คุณอาจสังเกตเห็นว่าวิธีนี้จะทำซ้ำข้อมูลบางส่วนโดยจัดเก็บความสัมพันธ์ไว้ทั้งในระเบียนของ Ada และในกลุ่ม ตอนนี้ alovelace ได้รับการจัดทำดัชนีภายใต้กลุ่ม และ techpioneers แสดงอยู่ในโปรไฟล์ของ Ada ดังนั้น หากต้องการลบ Ada ออกจากกลุ่ม คุณต้องอัปเดตใน 2 ที่
นี่คือความซ้ำซ้อนที่จำเป็นสำหรับความสัมพันธ์แบบ 2 ทาง ซึ่งช่วยให้คุณ ดึงข้อมูลสมาชิกของ Ada ได้อย่างรวดเร็วและมีประสิทธิภาพ แม้ว่ารายชื่อผู้ใช้หรือ กลุ่มจะขยายเป็นหลายล้านรายการ หรือกฎการรักษาความปลอดภัยของ Realtime Database ป้องกันไม่ให้เข้าถึงระเบียนบางรายการ
แนวทางนี้ ซึ่งเป็นการกลับด้านข้อมูลโดยแสดงรหัสเป็นคีย์และตั้งค่าเป็น "จริง" ทำให้การตรวจสอบคีย์เป็นเรื่องง่ายเพียงแค่การอ่าน /users/$uid/groups/$group_id และตรวจสอบว่าคีย์เป็น null หรือไม่ ดัชนีทำงานได้เร็วกว่าและมีประสิทธิภาพมากกว่าการค้นหาหรือสแกนข้อมูล