เริ่มต้นใช้งาน
โปรดดูคําแนะนํา Get Started
ก่อนหากยังไม่เคย
ตั้งค่าแอปและเข้าถึงฐานข้อมูล
รับ DatabaseReference
ในการเขียนข้อมูลไปยังฐานข้อมูล คุณต้องมีอินสแตนซ์ของ DatabaseReference
:
// Get the root reference location of the database. firebase::database::DatabaseReference dbref = database->GetReference();
กำลังบันทึกข้อมูล
การเขียนข้อมูลไปยังฐานข้อมูลเรียลไทม์ของ Firebase มี 4 วิธีดังนี้
วิธีการ | การใช้งานทั่วไป |
---|---|
SetValue() |
เขียนหรือแทนที่ข้อมูลในเส้นทางที่กำหนด เช่น
users/<user-id>/<username> . |
PushChild() |
เพิ่มลงในรายการข้อมูล ทุกครั้งที่คุณโทร
Push() โดย Firebase จะสร้างคีย์ที่ไม่ซ้ำกันซึ่งใช้ได้ด้วยเช่นกัน
เป็นตัวระบุที่ไม่ซ้ำกัน เช่น
user-scores/<user-id>/<unique-score-id> . |
UpdateChildren() |
อัปเดตคีย์บางรายการสำหรับเส้นทางที่กำหนดโดยไม่ต้องแทนที่ ข้อมูลดังกล่าว |
RunTransaction() |
อัปเดตข้อมูลที่ซับซ้อนที่อาจเสียหายจากการอัปเดตพร้อมกัน |
เขียน อัปเดต หรือลบข้อมูลที่ข้อมูลอ้างอิง
การดำเนินการเขียนพื้นฐาน
สำหรับการดำเนินการเขียนพื้นฐาน คุณสามารถใช้ SetValue()
เพื่อบันทึกข้อมูลไปยัง
ข้อมูลอ้างอิงที่ระบุ โดยแทนที่ข้อมูลที่มีอยู่ในเส้นทางนั้น คุณใช้
ในการส่งประเภทที่ JSON ยอมรับผ่านประเภทตัวแปรที่รองรับ:
- Null (การดำเนินการนี้จะลบข้อมูล)
- จำนวนเต็ม (64 บิต)
- ตัวเลขทศนิยมแบบความแม่นยำสองเท่า
- บูลีน
- สตริง
- เวกเตอร์ของตัวแปร
- การแมปสตริงกับตัวแปร
การใช้ SetValue()
ด้วยวิธีนี้จะเขียนทับข้อมูลในตำแหน่งที่ระบุ
รวมถึงโหนดย่อย อย่างไรก็ตาม คุณยังอัปเดตรายการย่อยได้โดยไม่ต้อง
การเขียนออบเจ็กต์ใหม่ทั้งหมด หากต้องการอนุญาตให้ผู้ใช้อัปเดตโปรไฟล์ของตนเอง
คุณสามารถอัปเดตชื่อผู้ใช้ได้ดังนี้
dbref.Child("users").Child(userId).Child("username").SetValue(name);
ต่อท้ายรายการข้อมูล
ใช้เมธอด PushChild()
เพื่อต่อท้ายรายการในแอปพลิเคชันที่มีผู้ใช้หลายคน
เมธอด PushChild()
จะสร้างคีย์ที่ไม่ซ้ำกันทุกครั้งที่มีการเรียก
ลงในการอ้างอิง Firebase ที่ระบุ ด้วยการใช้สิ่งเหล่านี้
คีย์ที่สร้างขึ้นโดยอัตโนมัติสำหรับองค์ประกอบใหม่แต่ละรายการในรายการ โดยไคลเอ็นต์หลายราย
เพิ่มเด็กไปยังตำแหน่งที่ตั้งเดียวกันพร้อมกันโดยไม่มีความขัดแย้งในการเขียน
คีย์ที่ไม่ซ้ำกันที่ PushChild()
สร้างขึ้นจะอิงตามการประทับเวลา ดังนั้นรายการจึง
จะเรียงตามลำดับเวลาโดยอัตโนมัติ
คุณสามารถใช้การอ้างอิงข้อมูลใหม่ที่แสดงผลโดยเมธอด PushChild()
ได้
เพื่อรับค่าของคีย์ที่สร้างขึ้นโดยอัตโนมัติของบุตรหลานหรือตั้งค่าข้อมูลสำหรับบุตรหลาน
การเรียกใช้ GetKey()
ในการอ้างอิง PushChild()
จะแสดงค่าของแอตทริบิวต์
ที่สร้างโดยอัตโนมัติ
อัปเดตช่องข้อมูลที่เฉพาะเจาะจง
เพื่อเขียนไปยังโหนดย่อยที่ต้องการพร้อมกันโดยไม่เขียนทับโหนดอื่น
โหนดย่อย ให้ใช้เมธอด UpdateChildren()
เมื่อโทรหา UpdateChildren()
คุณจะอัปเดตค่าย่อยระดับล่างได้โดย
โดยระบุเส้นทางของคีย์นี้ หากมีการจัดเก็บข้อมูลในหลายตำแหน่งเพื่อปรับขนาด
คุณจะสามารถอัปเดตอินสแตนซ์ทั้งหมดของข้อมูลนั้นได้โดยใช้
การขยายข้อมูล ตัวอย่างเช่น
เกมอาจมีคลาส LeaderboardEntry
ในลักษณะนี้
class LeaderboardEntry { std::string uid; int score = 0; public: LeaderboardEntry() { } LeaderboardEntry(std::string uid, int score) { this->uid = uid; this->score = score; } std::map<std::string, Object> ToMap() { std::map<string, Variant> result = new std::map<string, Variant>(); result["uid"] = Variant(uid); result["score"] = Variant(score); return result; } }
เพื่อสร้าง LeaderboardEntry
และอัปเดตให้เป็นคะแนนล่าสุดพร้อมกัน
และรายการคะแนนของผู้ใช้เอง เกมจะใช้โค้ดต่อไปนี้
void WriteNewScore(std::string userId, int score) { // Create new entry at /user-scores/$userid/$scoreid and at // /leaderboard/$scoreid simultaneously std::string key = dbref.Child("scores").PushChild().GetKey(); LeaderBoardEntry entry = new LeaderBoardEntry(userId, score); std::map<std::string, Variant> entryValues = entry.ToMap(); std::map<string, Variant> childUpdates = new std::map<string, Variant>(); childUpdates["/scores/" + key] = entryValues; childUpdates["/user-scores/" + userId + "/" + key] = entryValues; dbref.UpdateChildren(childUpdates); }
ตัวอย่างนี้ใช้ PushChild()
เพื่อสร้างรายการในโหนดที่มี
รายการสำหรับผู้ใช้ทั้งหมดที่ /scores/$key
และเรียกข้อมูลคีย์พร้อมกันด้วย
key()
จากนั้นสามารถใช้คีย์เพื่อสร้างรายการที่ 2 ในส่วน
คะแนนในนาทีที่ /user-scores/$userid/$key
การใช้เส้นทางเหล่านี้จะทำให้คุณสามารถอัปเดตสถานที่หลายแห่งพร้อมกันใน
โครงสร้าง JSON ที่มีการเรียกไปยัง UpdateChildren()
ครั้งเดียว เช่น
สร้างรายการใหม่ในทั้ง 2 ตำแหน่ง การอัปเดตในเวลาเดียวกันทำให้รายการนี้
ต่างกันตรงที่ว่าการอัปเดตทั้งหมดสำเร็จหรือล้มเหลว
ลบข้อมูล
วิธีที่ง่ายที่สุดในการลบข้อมูลคือการเรียกใช้ RemoveValue()
ตามการอ้างอิง
ตำแหน่งของข้อมูลนั้น
ก็ลบได้ด้วยการระบุ null
Variant
เป็นค่าสำหรับการเขียนอื่น
เช่น SetValue()
หรือ UpdateChildren()
คุณใช้
เทคนิคที่มี UpdateChildren()
ในการลบรายการย่อยหลายรายการใน API เดียว
การโทร
รับข้อมูลเมื่อมีการคอมมิตข้อมูลของคุณ
หากต้องการทราบเมื่อข้อมูลของคุณผูกอยู่กับเซิร์ฟเวอร์ฐานข้อมูลเรียลไทม์ของ Firebase ให้ตรวจสอบ ผลลัพธ์อนาคตสำหรับความสำเร็จ
บันทึกข้อมูลเป็นธุรกรรม
เมื่อทำงานกับข้อมูลที่อาจเสียหายจากการเชื่อมต่อพร้อมกัน
เช่น ตัวนับที่เพิ่มขึ้น คุณสามารถใช้
การดำเนินการธุรกรรม
คุณกำหนดให้การดำเนินการนี้มีฟังก์ชัน DoTransaction
ฟังก์ชันอัปเดตนี้ใช้เวลา
สถานะปัจจุบันของข้อมูลเป็นอาร์กิวเมนต์ และแสดงผลสถานะที่ต้องการใหม่
ที่คุณต้องการเขียน ถ้าไคลเอ็นต์อื่นเขียนไปยังตำแหน่งก่อนหน้า
เขียนค่าใหม่เรียบร้อยแล้ว ฟังก์ชันอัปเดตจะถูกเรียกใช้อีกครั้งพร้อมด้วย
ค่าปัจจุบันใหม่ และจะพยายามเขียนอีกครั้ง
เช่น ในเกมที่คุณอนุญาตให้ผู้ใช้อัปเดตลีดเดอร์บอร์ด คะแนนสูงสุด 5 อันดับ ได้แก่
void AddScoreToLeaders(std::string email, long score, DatabaseReference leaderBoardRef) { leaderBoardRef.RunTransaction([](firebase::database::MutableData* mutableData) { if (mutableData.children_count() >= MaxScores) { long minScore = LONG_MAX; MutableData *minVal = null; std::vector<MutableData> children = mutableData.children(); std::vector<MutableData>::iterator it; for (it = children.begin(); it != children.end(); ++it) { if (!it->value().is_map()) continue; long childScore = (long)it->Child("score").value().int64_value(); if (childScore < minScore) { minScore = childScore; minVal = &*it; } } if (minScore > score) { // The new score is lower than the existing 5 scores, abort. return kTransactionResultAbort; } // Remove the lowest score. children.Remove(minVal); } // Add the new high score. std::map<std::string, Variant> newScoreMap = new std::map<std::string, Variant>(); newScoreMap["score"] = score; newScoreMap["email"] = email; children.Add(newScoreMap); mutableData->set_value(children); return kTransactionResultSuccess; }); }
การใช้ธุรกรรมจะป้องกันไม่ให้ลีดเดอร์บอร์ดไม่ถูกต้องหากมีหลายรายการ ผู้ใช้บันทึกคะแนนในเวลาเดียวกันหรือไคลเอ็นต์มีข้อมูลเก่า หาก ปฏิเสธธุรกรรม เซิร์ฟเวอร์จะส่งคืนมูลค่าปัจจุบันไปยังไคลเอ็นต์ ซึ่งจะเรียกใช้ธุรกรรมอีกครั้งด้วยมูลค่าที่อัปเดตแล้ว ซึ่งจะเกิดซ้ำจนถึง ยอมรับธุรกรรมหรือพยายามดำเนินการหลายครั้งเกินไป
เขียนข้อมูลแบบออฟไลน์
หากลูกค้าสูญเสียการเชื่อมต่อเครือข่าย แอปจะยังคงทำงานต่อไป อย่างถูกต้อง
ลูกค้าทุกรายที่เชื่อมต่อกับฐานข้อมูล Firebase จะมีเวอร์ชันภายในของตนเอง ของข้อมูลที่ใช้งานอยู่ เมื่อเขียนข้อมูล ระบบจะเขียนลงในเวอร์ชันนี้ในเครื่อง ก่อน จากนั้นไคลเอ็นต์ Firebase จะซิงค์ข้อมูลนั้นกับฐานข้อมูลระยะไกล เซิร์ฟเวอร์และไคลเอ็นต์อื่นๆ อย่าง "สุดความสามารถ" พื้นฐาน
ด้วยเหตุนี้ การเขียนทั้งหมดไปยังฐานข้อมูลจะทริกเกอร์เหตุการณ์ในระบบทันที ข้อมูลใดก็ตามที่เขียนไปยังเซิร์ฟเวอร์ ซึ่งหมายความว่าแอปของคุณจะยัง ตอบสนองตามอุปกรณ์โดยไม่คำนึงถึงเวลาในการตอบสนองหรือการเชื่อมต่อของเครือข่าย
เมื่อเชื่อมต่ออินเทอร์เน็ตอีกครั้งแล้ว แอปจะได้รับชุด เหตุการณ์เพื่อให้ไคลเอ็นต์ซิงค์กับสถานะเซิร์ฟเวอร์ปัจจุบันโดยไม่ต้อง เขียนโค้ดที่กำหนดเอง