حفظ البيانات

قبل البدء

قبل أن تتمكّن من استخدام Realtime Database، عليك إجراء ما يلي:

  • سجِّل مشروعك على Unity واضبطه لاستخدام Firebase.

    • إذا كان مشروعك في Unity يستخدم Firebase حاليًا، يكون تسجيلها وإعدادها لمنصة Firebase

    • وإذا لم يكن لديك مشروع Unity، يمكنك تنزيل نموذج تطبيق.

  • أضِف حزمة تطوير البرامج (SDK) Unity من Firebase (على وجه التحديد FirebaseDatabase.unitypackage) إلى لمشروع Unity الخاص بك.

تجدر الإشارة إلى أنّ إضافة منصة Firebase إلى مشروع Unity تتضمّن مهامًا في كلّ من وحدة تحكُّم Firebase وفي مشروع Unity المفتوح (على سبيل المثال، يمكنك تنزيل ملفات تهيئة Firebase من وحدة التحكم، ثم نقل إلى مشروع Unity).

حفظ البيانات

توجد خمس طرق لكتابة البيانات في قاعدة بيانات 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

لكتابة بيانات إلى قاعدة البيانات، أنت بحاجة إلى نسخة افتراضية من 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(). على سبيل المثال، قد يكون لديك فئة مستخدم بدت كما يلي:

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 ويمكن بعد ذلك استخدام المفتاح لإنشاء إدخال ثانٍ في ملف أحرز هدفا في /user-scores/$userid/$key.

باستخدام هذه المسارات، يمكنك إجراء تحديثات متزامنة للعديد من المواقع في شجرة JSON مع استدعاء واحد إلى UpdateChildrenAsync()، مثل كيف أن هذا سبيل المثال إلى إنشاء الإدخال الجديد في كلا الموقعين. جعلت التحديثات المتزامنة هذا بسيطة: إما أن تنجح جميع التحديثات أو تفشل جميع التحديثات.

حذف البيانات

وأبسط طريقة لحذف البيانات هي الاتصال بـ RemoveValue() على مرجع إلى لموقع تلك البيانات.

يمكنك أيضًا الحذف من خلال تحديد null كقيمة لعملية كتابة أخرى. عملية مثل SetValueAsync() أو UpdateChildrenAsync(). يمكنك استخدام هذه الصفحة أسلوب مع UpdateChildrenAsync() لحذف عدة عناصر فرعية في واجهة برمجة تطبيقات واحدة الاتصال.

يمكنك معرفة متى تكون بياناتك ملتزمة.

لمعرفة وقت التزام بياناتك بخادم قاعدة بيانات 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 تلك البيانات مع قاعدة البيانات البعيدة. مع العملاء الآخرين على "أفضل جهد" بشكل أساسي.

ونتيجةً لذلك، تؤدي جميع عمليات الكتابة في قاعدة البيانات إلى تشغيل الأحداث المحلية على الفور، قبل كتابة أي بيانات على الخادم. هذا يعني أنّ تطبيقك سيبقى سريع الاستجابة بغض النظر عن وقت استجابة الشبكة أو الاتصال.

وبمجرد إعادة الاتصال، يتلقى تطبيقك المجموعة المناسبة من بحيث يتزامن البرنامج مع حالة الخادم الحالية، دون الحاجة إلى وكتابة أي رمز مخصص.

الخطوات التالية