iT邦幫忙

2024 iThome 鐵人賽

DAY 19
0
Software Development

Unity黑科技揭秘:30個專業遊戲開發者必知的開發技巧系列 第 19

Unity Firestore - 使用 Firestore進行資料儲存!

  • 分享至 

  • xImage
  •  


Firestore 是基於Firebase的一種noSQL儲存方式
你可以在上面類似資料夾的方式儲存文件。

實戰步驟:
在C#開一個Interface

public interface IFirestore
{
    public void Initialize();
    public bool SaveData(string path, string document, Dictionary<string, object> dataDic);
    public void GetData(string path, string document,  Action<Dictionary<string, object>> callback);
    public void GetDataList(string path,  Action<List<Dictionary<string, object>>> callback);
    public bool DeleteData(string path, string document);
    public bool FilterData(string path, string key, FirestoreFilterType type, object condition,
        Action<List<Dictionary<string, object>>> callback);
}

實作:

public class YFirestore: IYFirestore
{
    private FirebaseFirestore FirestoreDB;

    public void Initialize()
    {
        FirestoreDB = FirebaseFirestore.DefaultInstance;
    }

    public bool SaveData(string path, string document, Dictionary<string, object> dataDic)
    {
        bool result = false;
        var docRef = FirestoreDB.Collection(path).Document(document);
        docRef.SetAsync(dataDic).ContinueWithOnMainThread(task =>
        {
            if (task.IsFaulted)
            {
                Debug.Log($"Firestore error: failed to add {document} data in the {path}. " +
                          $"Error: {task.Exception}");
                result = false;
            }
            else
            {
                Debug.Log($"Firestore: Successful Added {document} data in the {path}.");
                result = true;
            }
        });
        return result;
    }

    public void GetData(string path, string document,  Action<Dictionary<string, object>> callback)
    {
        CoroutineManager.Instance.StartCoroutine(GetDataCoroutine(path, document, callback));
        IEnumerator GetDataCoroutine(string dataPath, string dataDocument, Action<Dictionary<string, object>> 
            actionCallback) {
            DocumentReference docRef = FirestoreDB.Collection(dataPath).Document(dataDocument);
            var getSnapshotTask = docRef.GetSnapshotAsync();
            yield return new WaitUntil(() => getSnapshotTask.IsCompleted);
            DocumentSnapshot snapshot = getSnapshotTask.Result;

            if (snapshot.Exists)
            {
                Dictionary<string, object> dataDic = snapshot.ToDictionary();
                actionCallback?.Invoke(dataDic);
            }
            else
            {
                callback?.Invoke(null);
            }
        }
    }

    //implement GetData List By Given Path
    public void GetDataList(string path, Action<List<Dictionary<string, object>>> callback)
    {
        CoroutineManager.Instance.StartCoroutine(GetDataListCoroutine(path, callback));
        IEnumerator GetDataListCoroutine(string dataPath, Action<List<Dictionary<string, object>>> actionCallback)
        {
            CollectionReference collectionRef = FirestoreDB.Collection(dataPath);
            var getSnapshotTask = collectionRef.GetSnapshotAsync();
            yield return new WaitUntil(() => getSnapshotTask.IsCompleted);
            QuerySnapshot snapshot = getSnapshotTask.Result;
            List<Dictionary<string, object>> dataList = new List<Dictionary<string, object>>();
            foreach (DocumentSnapshot documentSnapshot in snapshot.Documents)
            {
                dataList.Add(documentSnapshot.ToDictionary());
            }
            actionCallback?.Invoke(dataList);
        }
    }

    public bool DeleteData(string path, string document)
    {
        DocumentReference docRef = FirestoreDB.Collection(path).Document(document);
        docRef.DeleteAsync().ContinueWithOnMainThread(task =>
        {
            if (task.IsFaulted)
            {
                Debug.Log($"Firestore: Failed to delete document in {path}: {task.Exception}");
                return false;
            }
            else
            {
                Debug.Log($"Firestore: Successfully deleted document {document} in {path}");
                return true;
            }
        });
        return false;
    }


    public bool FilterData(string path, string key, FirestoreFilterType type, object condition,
        Action<List<Dictionary<string, object>>> callback) {

        CollectionReference collectionRef = FirestoreDB.Collection(path);
        var query = type switch
        {
            FirestoreFilterType.WhereEqualTo => collectionRef.WhereEqualTo(key, condition),
            FirestoreFilterType.WhereGreaterThan => collectionRef.WhereGreaterThan(key, condition),
            FirestoreFilterType.WhereGreaterThanOrEqualTo => collectionRef.WhereGreaterThanOrEqualTo(key,
                condition),
            FirestoreFilterType.WhereNotEqualTo => collectionRef.WhereNotEqualTo(key, condition),
            FirestoreFilterType.WhereArrayContains => collectionRef.WhereArrayContains(key, condition),
            FirestoreFilterType.WhereLessThan => collectionRef.WhereLessThan(key, condition),
            FirestoreFilterType.WhereLessThanOrEqualTo => collectionRef.WhereLessThanOrEqualTo(key, condition),
            _ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
        };
        List<Dictionary<string, object>> dataDicList = new List<Dictionary<string, object>>();

        query.GetSnapshotAsync().ContinueWithOnMainThread(task =>
        {
            if (task.IsCompletedSuccessfully)
            {
                foreach (DocumentSnapshot documentSnapshot in task.Result.Documents)
                {
                    dataDicList.Add(documentSnapshot.ToDictionary());
                }

                callback?.Invoke(dataDicList);
                return true;
            }
            else
            {
                Debug.Log($"Query failed: {task.Exception.Message}");
                return false;
            }
        });
        return false;
    }
}

上一篇
Unity Firebase - 使用Firebase進行用戶註冊登入!
下一篇
Unity Adb - 使用ADB快速調用Android系統!
系列文
Unity黑科技揭秘:30個專業遊戲開發者必知的開發技巧25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言