Catch up on everthing we announced at this year's Firebase Summit. Learn more

บันทึกข้อมูล

ก่อนจะเริ่ม

ก่อนที่คุณจะสามารถใช้ เรียลไทม์ฐานข้อมูล คุณต้องไปที่:

  • ลงทะเบียนโครงการ Unity ของคุณและกำหนดค่าให้ใช้ Firebase

    • หากโปรเจ็กต์ Unity ของคุณใช้ Firebase อยู่แล้ว แสดงว่าได้ลงทะเบียนและกำหนดค่าสำหรับ Firebase แล้ว

    • หากคุณไม่ได้มีโครงการเอกภาพคุณสามารถดาวน์โหลด แอปพลิเคตัวอย่าง

  • เพิ่ม Firebase สามัคคี SDK (เฉพาะ FirebaseDatabase.unitypackage ) ให้กับโครงการความสามัคคีของคุณ

หมายเหตุว่าการเพิ่ม Firebase กับโครงการความสามัคคีของคุณเกี่ยวข้องกับงานทั้งใน Firebase คอนโซล และในโครงการความสามัคคีของคุณเปิด (ตัวอย่างเช่นคุณดาวน์โหลดไฟล์การกำหนดค่า Firebase จากคอนโซลแล้วย้ายไปลงในโครงการความสามัคคีของคุณ)

บันทึกข้อมูล

มีห้าวิธีในการเขียนข้อมูลไปยังฐานข้อมูลเรียลไทม์ของ Firebase:

วิธี การใช้งานทั่วไป
SetValueAsync() เขียนหรือเปลี่ยนข้อมูลไปยังเส้นทางที่กำหนดไว้เช่น users/<user-id>/<username>
SetRawJsonValueAsync() เขียนหรือเปลี่ยนข้อมูลที่มี Json ดิบเช่น users/<user-id>/<username>
Push() เพิ่มในรายการข้อมูล ครั้งที่คุณโทรทุก Push() , Firebase สร้างคีย์ที่ไม่ซ้ำกันที่ยังสามารถนำมาใช้เป็นตัวระบุไม่ซ้ำกันเช่น user-scores/<user-id>/<unique-score-id>
UpdateChildrenAsync() อัปเดตคีย์บางคีย์สำหรับพาธที่กำหนดโดยไม่ต้องแทนที่ข้อมูลทั้งหมด
RunTransaction() อัปเดตข้อมูลที่ซับซ้อนที่อาจเสียหายจากการอัพเดทพร้อมกัน

รับฐานข้อมูลอ้างอิง

เขียนข้อมูลไปยังฐานข้อมูลที่คุณต้องการตัวอย่างของ 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 ดิบและเรียก 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() วิธีการเพื่อให้ข้อมูลที่ผนวกเข้าไปในรายการในการใช้งานแบบ multiuser 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;
    }
}

ในการสร้าง LeaderboardEntry และอัปเดตเป็นฟีดคะแนนล่าสุดและรายการคะแนนของผู้ใช้พร้อมกัน เกมจะใช้โค้ดดังนี้:

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 ที่สำคัญนั้นจะสามารถใช้ในการสร้างรายการที่สองในคะแนนของผู้ใช้ที่ /user-scores/$userid/$key

ใช้เส้นทางเหล่านี้คุณสามารถดำเนินการปรับปรุงพร้อมกันหลาย ๆ สถานที่ในต้นไม้ JSON กับสายเดียวที่จะ UpdateChildrenAsync() เช่นวิธีเช่นนี้จะสร้างรายการใหม่ในสถานที่ทั้งสอง การอัปเดตพร้อมกันในลักษณะนี้เป็นแบบอะตอมมิก: การอัปเดตทั้งหมดสำเร็จหรือการอัปเดตทั้งหมดล้มเหลว

ลบข้อมูล

วิธีที่ง่ายที่สุดในการลบข้อมูลคือการเรียก RemoveValue() ในการอ้างอิงถึงตำแหน่งของข้อมูลว่า

นอกจากนี้คุณยังสามารถลบโดยระบุ null เป็นค่าสำหรับการดำเนินการเขียนอีกเช่น SetValueAsync() หรือ UpdateChildrenAsync() คุณสามารถใช้เทคนิคนี้กับ UpdateChildrenAsync() ลบเด็กหลายในการเรียก API เดียว

รู้ว่าข้อมูลของคุณมีความมุ่งมั่นเมื่อใด

หากต้องการทราบว่าข้อมูลของคุณถูกส่งไปยังเซิร์ฟเวอร์ฐานข้อมูลเรียลไทม์ของ Firebase เมื่อใด คุณสามารถเพิ่มความต่อเนื่องได้ ทั้งสอง SetValueAsync() และ UpdateChildrenAsync() กลับมาเป็น Task ที่ช่วยให้คุณรู้ว่าเมื่อดำเนินการเสร็จสมบูรณ์ ถ้าโทรไม่สำเร็จด้วยเหตุผลใดก็ตามงานเมื่อต้องการ IsFaulted จะเป็นจริงกับ Exception คุณสมบัติที่แสดงให้เห็นว่าทำไมความล้มเหลวที่เกิดขึ้น

บันทึกข้อมูลเป็นธุรกรรม

เมื่อทำงานกับข้อมูลที่อาจจะเสียหายจากการปรับเปลี่ยนพร้อมกันเช่นเคาน์เตอร์เพิ่มขึ้นคุณสามารถใช้ การดำเนินการทำธุรกรรม คุณจะให้การดำเนินการนี้ Func การปรับปรุงนี้ Func เตะสถานะปัจจุบันของข้อมูลเป็นอาร์กิวเมนต์และผลตอบแทนรัฐที่ต้องการใหม่ที่คุณต้องการที่จะเขียน หากไคลเอนต์อื่นเขียนไปยังตำแหน่งก่อนที่ค่าใหม่ของคุณจะเขียนได้สำเร็จ ฟังก์ชันอัพเดตของคุณจะถูกเรียกอีกครั้งด้วยค่าปัจจุบันใหม่และลองเขียนใหม่

ตัวอย่างเช่น ในเกม คุณสามารถอนุญาตให้ผู้ใช้อัปเดตกระดานผู้นำด้วยคะแนนสูงสุดห้าคะแนน:

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 จะซิงโครไนซ์ข้อมูลนั้นกับเซิร์ฟเวอร์ฐานข้อมูลระยะไกลและกับไคลเอนต์อื่น ๆ ด้วย "ความพยายามอย่างดีที่สุด"

ด้วยเหตุนี้ การเขียนทั้งหมดไปยังฐานข้อมูลจะทริกเกอร์เหตุการณ์ในเครื่องทันที ก่อนที่ข้อมูลใดๆ จะถูกเขียนไปยังเซิร์ฟเวอร์ ซึ่งหมายความว่าแอปของคุณยังคงตอบสนองโดยไม่คำนึงถึงเวลาแฝงของเครือข่ายหรือการเชื่อมต่อ

เมื่อสร้างการเชื่อมต่อขึ้นใหม่แล้ว แอปของคุณจะได้รับชุดเหตุการณ์ที่เหมาะสม เพื่อให้ไคลเอ็นต์ซิงค์กับสถานะเซิร์ฟเวอร์ปัจจุบัน โดยไม่ต้องเขียนโค้ดที่กำหนดเองใดๆ

ขั้นตอนถัดไป