ก่อนเริ่มต้น
ก่อนที่จะใช้งานได้ Realtime Database คุณต้องทำดังนี้
ลงทะเบียนโปรเจ็กต์ Unity และกำหนดค่าให้ใช้ Firebase
หากโปรเจ็กต์ Unity ของคุณใช้ Firebase อยู่แล้ว ก็หมายความว่า ลงทะเบียนและกำหนดค่าสำหรับ Firebase แล้ว
หากไม่มีโปรเจ็กต์ Unity คุณสามารถดาวน์โหลด ตัวอย่างแอป
เพิ่ม Firebase Unity SDK (โดยเฉพาะ
FirebaseDatabase.unitypackage
) ไปยัง โปรเจ็กต์ Unity
โปรดทราบว่าการเพิ่ม Firebase ลงในโปรเจ็กต์ Unity จะเกี่ยวข้องกับงานทั้งใน คอนโซล Firebase และในโปรเจ็กต์ Unity ที่เปิดอยู่ (เช่น คุณดาวน์โหลดไฟล์การกำหนดค่า Firebase จากคอนโซล แล้วย้าย ลงในโปรเจ็กต์ Unity)
กำลังบันทึกข้อมูล
การเขียนข้อมูลไปยัง Firebase Realtime Database มี 5 วิธีดังนี้
วิธีการ | การใช้งานทั่วไป |
---|---|
SetValueAsync() |
เขียนหรือแทนที่ข้อมูลในเส้นทางที่กำหนด เช่น
users/<user-id>/<username> |
SetRawJsonValueAsync() |
เขียนหรือแทนที่ข้อมูลด้วย Json แบบ Raw เช่น
users/<user-id>/<username> |
Push() |
เพิ่มลงในรายการข้อมูล ทุกครั้งที่คุณโทร
Push() โดย Firebase จะสร้างคีย์ที่ไม่ซ้ำกันซึ่งใช้ได้ด้วยเช่นกัน
เป็นตัวระบุที่ไม่ซ้ำกัน เช่น
user-scores/<user-id>/<unique-score-id> |
UpdateChildrenAsync() |
อัปเดตคีย์บางรายการสำหรับเส้นทางที่กำหนดโดยไม่ต้องแทนที่ ข้อมูลดังกล่าว |
RunTransaction() |
อัปเดตข้อมูลที่ซับซ้อนที่อาจเสียหายจากการอัปเดตพร้อมกัน |
รับ DatabaseReference
ในการเขียนข้อมูลไปยังฐานข้อมูล คุณต้องมีอินสแตนซ์ของ DatabaseReference
:
using Firebase; using Firebase.Database; public class MyScript: MonoBehaviour { void Start() { // Get the root reference location of the database. DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference; } }
เขียน อัปเดต หรือลบข้อมูลที่ข้อมูลอ้างอิง
การดำเนินการเขียนพื้นฐาน
สำหรับการดำเนินการเขียนพื้นฐาน คุณสามารถใช้ SetValueAsync()
เพื่อบันทึกข้อมูลไปยัง
ข้อมูลอ้างอิงที่ระบุ โดยแทนที่ข้อมูลที่มีอยู่ในเส้นทางนั้น คุณใช้
ในการส่งประเภทที่สอดคล้องกับประเภท JSON ที่มีอยู่ดังนี้
string
long
double
bool
Dictionary<string, Object>
List<Object>
หากใช้ออบเจ็กต์ C# ที่พิมพ์ไว้ คุณจะใช้ JsonUtility.ToJson()
ในตัวได้
เพื่อแปลงวัตถุเป็น Json แบบ Raw และเรียกใช้ SetRawJsonValueAsync()
เช่น คุณอาจมีคลาส User ที่มีลักษณะดังนี้
public class User { public string username; public string email; public User() { } public User(string username, string email) { this.username = username; this.email = email; } }
คุณเพิ่มผู้ใช้ที่มี SetRawJsonValueAsync()
ได้โดยทำดังนี้
private void writeNewUser(string userId, string name, string email) { User user = new User(name, email); string json = JsonUtility.ToJson(user); mDatabaseRef.Child("users").Child(userId).SetRawJsonValueAsync(json); }
การใช้ SetValueAsync()
หรือ SetRawJsonValueAsync()
ในลักษณะนี้จะเขียนทับข้อมูล
ในตำแหน่งที่ระบุ รวมถึงโหนดย่อย อย่างไรก็ตาม คุณยังสามารถ
อัปเดตรายการย่อยโดยไม่ต้องเขียนออบเจ็กต์ทั้งหมดใหม่ หากต้องการอนุญาตผู้ใช้
เพื่ออัปเดตโปรไฟล์ของพวกเขา คุณสามารถอัปเดตชื่อผู้ใช้ได้ดังนี้:
mDatabaseRef.Child("users").Child(userId).Child("username").SetValueAsync(name);
ต่อท้ายรายการข้อมูล
ใช้เมธอด Push()
เพื่อต่อท้ายรายการในแอปพลิเคชันที่มีผู้ใช้หลายคน
เมธอด Push()
จะสร้างคีย์ที่ไม่ซ้ำกันทุกครั้งที่มีการเรียก
ลงในการอ้างอิง Firebase ที่ระบุ ด้วยการใช้สิ่งเหล่านี้
คีย์ที่สร้างขึ้นโดยอัตโนมัติสำหรับองค์ประกอบใหม่แต่ละรายการในรายการ โดยไคลเอ็นต์หลายราย
เพิ่มเด็กไปยังตำแหน่งที่ตั้งเดียวกันพร้อมกันโดยไม่มีความขัดแย้งในการเขียน
คีย์ที่ไม่ซ้ำกันที่ Push()
สร้างขึ้นจะอิงตามการประทับเวลา ดังนั้นรายการจึง
จะเรียงตามลำดับเวลาโดยอัตโนมัติ
คุณสามารถใช้การอ้างอิงข้อมูลใหม่ที่แสดงโดยเมธอด Push()
เพื่อเรียก
ค่าของคีย์ที่สร้างขึ้นโดยอัตโนมัติของบุตรหลานหรือตั้งค่าข้อมูลสำหรับบุตรหลาน การโทร
Key
ในข้อมูลอ้างอิง Push()
แสดงผลค่าของแอตทริบิวต์
ที่สร้างโดยอัตโนมัติ
อัปเดตช่องข้อมูลที่เฉพาะเจาะจง
เพื่อเขียนไปยังโหนดย่อยที่ต้องการพร้อมกันโดยไม่เขียนทับโหนดอื่น
โหนดย่อย ให้ใช้เมธอด UpdateChildrenAsync()
เมื่อโทรหา UpdateChildrenAsync()
คุณจะอัปเดตค่าย่อยระดับล่างได้โดย
โดยระบุเส้นทางของคีย์นี้ หากมีการจัดเก็บข้อมูลในหลายตำแหน่งเพื่อปรับขนาด
คุณจะสามารถอัปเดตอินสแตนซ์ทั้งหมดของข้อมูลนั้นได้โดยใช้
การขยายข้อมูล ตัวอย่างเช่น
เกมอาจมีคลาส LeaderboardEntry
ในลักษณะนี้
public class LeaderboardEntry { public string uid; public int score = 0; public LeaderboardEntry() { } public LeaderboardEntry(string uid, int score) { this.uid = uid; this.score = score; } public Dictionary<string, Object> ToDictionary() { Dictionary<string, Object> result = new Dictionary<string, Object>(); result["uid"] = uid; result["score"] = score; return result; } }
เพื่อสร้างลีดเดอร์บอร์ดรายการและอัปเดตให้เป็นคะแนนล่าสุดไปพร้อมๆ กัน และรายการคะแนนของผู้ใช้เอง เกมจะใช้โค้ดดังนี้
private void WriteNewScore(string userId, int score) { // Create new entry at /user-scores/$userid/$scoreid and at // /leaderboard/$scoreid simultaneously string key = mDatabase.Child("scores").Push().Key; LeaderBoardEntry entry = new LeaderBoardEntry(userId, score); Dictionary<string, Object> entryValues = entry.ToDictionary(); Dictionary<string, Object> childUpdates = new Dictionary<string, Object>(); childUpdates["/scores/" + key] = entryValues; childUpdates["/user-scores/" + userId + "/" + key] = entryValues; mDatabase.UpdateChildrenAsync(childUpdates); }
ตัวอย่างนี้ใช้ Push()
เพื่อสร้างรายการในโหนดที่มีรายการสำหรับ
ผู้ใช้ทั้งหมดที่ /scores/$key
และดึงคีย์ไปพร้อมๆ กันด้วย
Key
จากนั้นสามารถใช้คีย์เพื่อสร้างรายการที่ 2 ในส่วน
คะแนนในนาทีที่ /user-scores/$userid/$key
การใช้เส้นทางเหล่านี้จะทำให้คุณสามารถอัปเดตสถานที่หลายแห่งพร้อมกันใน
โครงสร้าง JSON ที่มีการเรียกไปยัง UpdateChildrenAsync()
ครั้งเดียว เช่น
สร้างรายการใหม่ในทั้ง 2 ตำแหน่ง การอัปเดตพร้อมกันทำให้รายการนี้
ต่างกันตรงที่ว่าการอัปเดตทั้งหมดสำเร็จหรือล้มเหลว
ลบข้อมูล
วิธีที่ง่ายที่สุดในการลบข้อมูลคือการเรียกใช้ RemoveValue()
ตามการอ้างอิง
ตำแหน่งของข้อมูลนั้น
ก็ลบได้ด้วยการระบุ null
เป็นค่าสำหรับการเขียนอื่น
เช่น SetValueAsync()
หรือ UpdateChildrenAsync()
คุณใช้
เทคนิคที่มี UpdateChildrenAsync()
ในการลบรายการย่อยหลายรายการใน API เดียว
การโทร
รับข้อมูลเมื่อมีการคอมมิตข้อมูลของคุณ
หากต้องการทราบว่าเมื่อใดที่ข้อมูลของคุณผูกอยู่กับเซิร์ฟเวอร์ Firebase Realtime Database คุณต้องทำดังนี้
เพิ่มข้อความต่อเนื่องได้ ทั้ง SetValueAsync()
และ UpdateChildrenAsync()
แสดงผล Task
ที่จะช่วยให้คุณทราบได้เมื่อการดำเนินการเสร็จสมบูรณ์ หาก
การโทรไม่สำเร็จด้วยเหตุผลใดก็ตาม Tasks IsFaulted
จะเป็นจริงด้วย
พร็อพเพอร์ตี้ Exception
ที่ระบุสาเหตุของความล้มเหลว
บันทึกข้อมูลเป็นธุรกรรม
เมื่อทำงานกับข้อมูลที่อาจเสียหายจากการเชื่อมต่อพร้อมกัน
เช่น ตัวนับที่เพิ่มขึ้น คุณสามารถใช้
การดำเนินการธุรกรรม
คุณกำหนดให้การดำเนินการนี้เป็น Func
การอัปเดต Func
นี้จะเปลี่ยนสถานะปัจจุบัน
ของข้อมูลเป็นอาร์กิวเมนต์ และส่งคืนสถานะใหม่ที่ต้องการ
เขียน หากไคลเอ็นต์อื่นเขียนไปยังตำแหน่งนั้นก่อนค่าใหม่ของคุณคือ
เขียนสำเร็จแล้ว ฟังก์ชันอัปเดตของคุณจะถูกเรียกอีกครั้งด้วยฟังก์ชัน
และพยายามเขียนอีกครั้ง
เช่น ในเกมที่คุณอนุญาตให้ผู้ใช้อัปเดตลีดเดอร์บอร์ด คะแนนสูงสุด 5 อันดับ ได้แก่
private void AddScoreToLeaders(string email, long score, DatabaseReference leaderBoardRef) { leaderBoardRef.RunTransaction(mutableData => { List<object> leaders = mutableData.Value as List<object> if (leaders == null) { leaders = new List<object>(); } else if (mutableData.ChildrenCount >= MaxScores) { long minScore = long.MaxValue; object minVal = null; foreach (var child in leaders) { if (!(child is Dictionary<string, object>)) continue; long childScore = (long) ((Dictionary<string, object>)child)["score"]; if (childScore < minScore) { minScore = childScore; minVal = child; } } if (minScore > score) { // The new score is lower than the existing 5 scores, abort. return TransactionResult.Abort(); } // Remove the lowest score. leaders.Remove(minVal); } // Add the new high score. Dictionary<string, object> newScoreMap = new Dictionary<string, object>(); newScoreMap["score"] = score; newScoreMap["email"] = email; leaders.Add(newScoreMap); mutableData.Value = leaders; return TransactionResult.Success(mutableData); }); }
การใช้ธุรกรรมจะป้องกันไม่ให้ลีดเดอร์บอร์ดไม่ถูกต้องหากมีหลายรายการ ผู้ใช้บันทึกคะแนนในเวลาเดียวกันหรือไคลเอ็นต์มีข้อมูลเก่า หาก ปฏิเสธธุรกรรม เซิร์ฟเวอร์จะส่งคืนมูลค่าปัจจุบันไปยังไคลเอ็นต์ ซึ่งจะเรียกใช้ธุรกรรมอีกครั้งด้วยมูลค่าที่อัปเดตแล้ว ซึ่งจะเกิดซ้ำจนถึง ยอมรับธุรกรรมหรือพยายามดำเนินการหลายครั้งเกินไป
เขียนข้อมูลแบบออฟไลน์
หากลูกค้าสูญเสียการเชื่อมต่อเครือข่าย แอปจะยังคงทำงานต่อไป อย่างถูกต้อง
ลูกค้าทุกรายที่เชื่อมต่อกับฐานข้อมูล Firebase จะมีเวอร์ชันภายในของตนเอง ของข้อมูลที่ใช้งานอยู่ เมื่อเขียนข้อมูล ระบบจะเขียนลงในเวอร์ชันนี้ในเครื่อง ก่อน จากนั้นไคลเอ็นต์ Firebase จะซิงค์ข้อมูลนั้นกับฐานข้อมูลระยะไกล เซิร์ฟเวอร์และไคลเอ็นต์อื่นๆ อย่าง "สุดความสามารถ" พื้นฐาน
ด้วยเหตุนี้ การเขียนทั้งหมดไปยังฐานข้อมูลจะทริกเกอร์เหตุการณ์ในระบบทันที ข้อมูลใดก็ตามที่เขียนไปยังเซิร์ฟเวอร์ ซึ่งหมายความว่าแอปของคุณจะยัง ตอบสนองตามอุปกรณ์โดยไม่คำนึงถึงเวลาในการตอบสนองหรือการเชื่อมต่อของเครือข่าย
เมื่อเชื่อมต่ออินเทอร์เน็ตอีกครั้งแล้ว แอปจะได้รับชุด เหตุการณ์เพื่อให้ไคลเอ็นต์ซิงค์กับสถานะเซิร์ฟเวอร์ปัจจุบันโดยไม่ต้อง เขียนโค้ดที่กำหนดเอง