ก่อนที่คุณจะเริ่ม
ก่อนที่คุณจะสามารถใช้ Realtime Database คุณต้อง:
ลงทะเบียนโปรเจ็กต์ Unity ของคุณและกำหนดค่าให้ใช้ Firebase
หากโปรเจ็กต์ Unity ของคุณใช้ Firebase อยู่แล้ว แสดงว่ามีการลงทะเบียนและกำหนดค่าสำหรับ Firebase แล้ว
หากคุณไม่มีโปรเจ็กต์ Unity คุณสามารถดาวน์โหลด แอปตัวอย่าง ได้
เพิ่ม Firebase Unity SDK (โดยเฉพาะ
FirebaseDatabase.unitypackage
) ให้กับโปรเจ็กต์ Unity ของคุณ
โปรดทราบว่าการเพิ่ม Firebase ให้กับโปรเจ็กต์ Unity ของคุณเกี่ยวข้องกับงานทั้งใน คอนโซล Firebase และในโปรเจ็กต์ Unity ที่เปิดอยู่ของคุณ (เช่น คุณดาวน์โหลดไฟล์การกำหนดค่า Firebase จากคอนโซล จากนั้นย้ายไฟล์เหล่านั้นไปยังโปรเจ็กต์ Unity ของคุณ)
โครงสร้างข้อมูล
คู่มือนี้ครอบคลุมแนวคิดหลักบางส่วนในสถาปัตยกรรมข้อมูลและแนวทางปฏิบัติที่ดีที่สุดในการจัดโครงสร้างข้อมูล JSON ในฐานข้อมูล Firebase Realtime ของคุณ
การสร้างฐานข้อมูลที่มีโครงสร้างอย่างเหมาะสมนั้นต้องใช้การคิดล่วงหน้าค่อนข้างมาก สิ่งสำคัญที่สุดคือ คุณต้องวางแผนว่าจะบันทึกข้อมูลอย่างไรและดึงข้อมูลในภายหลังเพื่อให้กระบวนการนั้นง่ายที่สุดเท่าที่จะเป็นไปได้
โครงสร้างข้อมูลเป็นอย่างไร: เป็นแผนผัง JSON
ข้อมูลฐานข้อมูล Firebase Realtime ทั้งหมดจะถูกจัดเก็บเป็นออบเจ็กต์ JSON คุณสามารถนึกถึงฐานข้อมูลว่าเป็นแผนผัง JSON ที่โฮสต์บนคลาวด์ ไม่เหมือนกับฐานข้อมูล SQL ไม่มีตารางหรือบันทึก เมื่อคุณเพิ่มข้อมูลลงในแผนผัง JSON ข้อมูลดังกล่าวจะกลายเป็นโหนดในโครงสร้าง JSON ที่มีอยู่พร้อมกับคีย์ที่เกี่ยวข้อง คุณสามารถระบุคีย์ของคุณเองได้ เช่น ID ผู้ใช้หรือชื่อความหมาย หรือระบุคีย์ให้คุณโดยใช้วิธี Push()
หากคุณสร้างคีย์ของคุณเอง คีย์เหล่านั้นจะต้องเข้ารหัส UTF-8 มีขนาดสูงสุดได้ 768 ไบต์ และไม่สามารถมี .
, $
, #
, [
, ]
, /
, หรืออักขระควบคุม ASCII 0-31 หรือ 127 คุณไม่สามารถใช้อักขระควบคุม ASCII ในค่าเหล่านั้นได้เช่นกัน
ตัวอย่างเช่น ลองใช้แอปพลิเคชันแชทที่อนุญาตให้ผู้ใช้จัดเก็บโปรไฟล์พื้นฐานและรายชื่อผู้ติดต่อ โปรไฟล์ผู้ใช้ทั่วไปจะอยู่ที่พาธ เช่น /users/$uid
ผู้ใช้ alovelace
อาจมีรายการฐานข้อมูลที่มีลักษณะดังนี้:
{ "users": { "alovelace": { "name": "Ada Lovelace", "contacts": { "ghopper": true }, }, "ghopper": { ... }, "eclarke": { ... } } }
แม้ว่าฐานข้อมูลจะใช้แผนผัง JSON แต่ข้อมูลที่จัดเก็บไว้ในฐานข้อมูลสามารถแสดงเป็นประเภทดั้งเดิมบางประเภทที่สอดคล้องกับประเภท JSON ที่มีอยู่ เพื่อช่วยให้คุณเขียนโค้ดที่สามารถบำรุงรักษาได้มากขึ้น
แนวทางปฏิบัติที่ดีที่สุดสำหรับโครงสร้างข้อมูล
หลีกเลี่ยงการซ้อนข้อมูล
เนื่องจากฐานข้อมูลเรียลไทม์ของ Firebase อนุญาตให้ซ้อนข้อมูลได้ลึกถึง 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 ตอบสนองและรวดเร็ว
สร้างข้อมูลที่ปรับขนาด
เมื่อสร้างแอป การดาวน์โหลดชุดย่อยของรายการมักจะดีกว่า นี่เป็นเรื่องปกติโดยเฉพาะอย่างยิ่งหากรายการมีบันทึกหลายพันรายการ เมื่อความสัมพันธ์นี้เป็นแบบคงที่และมีทิศทางเดียว คุณสามารถซ้อนอ็อบเจ็กต์ลูกไว้ใต้พาเรนต์ได้
บางครั้ง ความสัมพันธ์นี้อาจมีการเปลี่ยนแปลงมากขึ้น หรืออาจจำเป็นต้องทำให้ข้อมูลนี้เป็นปกติ หลายครั้งคุณสามารถทำให้ข้อมูลเป็นปกติได้โดยใช้คิวรีเพื่อดึงชุดย่อยของข้อมูล ดังที่อธิบายไว้ใน เรียกข้อมูล
แต่ถึงอย่างนั้นก็อาจจะไม่เพียงพอ ตัวอย่างเช่น พิจารณาความสัมพันธ์แบบสองทางระหว่างผู้ใช้และกลุ่ม ผู้ใช้สามารถอยู่ในกลุ่มได้ และกลุ่มจะประกอบด้วยรายชื่อผู้ใช้ เมื่อถึงเวลาต้องตัดสินใจว่าผู้ใช้อยู่ในกลุ่มใด สิ่งต่างๆ จะซับซ้อนขึ้น
สิ่งที่จำเป็นคือวิธีที่หรูหราในการแสดงรายการกลุ่มที่ผู้ใช้เป็นสมาชิกและดึงข้อมูลเฉพาะสำหรับกลุ่มเหล่านั้น ดัชนี ของกลุ่มสามารถช่วยได้มากที่นี่:
// 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 ได้อย่างรวดเร็วและมีประสิทธิภาพ แม้ว่ารายชื่อผู้ใช้หรือกลุ่มจะมีจำนวนเป็นล้านหรือเมื่อกฎความปลอดภัยของฐานข้อมูลเรียลไทม์ป้องกันการเข้าถึงบันทึกบางส่วน
วิธีการนี้ เป็นการกลับข้อมูลโดยการแสดงรายการ ID เป็นคีย์และตั้งค่าให้เป็นจริง ทำให้การตรวจสอบคีย์ทำได้ง่ายเพียงแค่อ่าน /users/$uid/groups/$group_id
และตรวจสอบว่าเป็น null
หรือไม่ ดัชนีเร็วกว่าและมีประสิทธิภาพมากกว่าการสืบค้นหรือสแกนข้อมูลอย่างมาก