MIF_E31221357/Assets/Scripts/DBManager.cs

263 lines
9.3 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase;
using Firebase.Database;
using Firebase.Extensions;
using System;
public class DBManager : MonoBehaviour
{
public static bool isFirebaseReady = false;
public class UserData
{
public string username;
public string kelas;
public string absen;
public int pretest;
public int posttest;
}
void Awake()
{
DontDestroyOnLoad(this.gameObject);
StartCoroutine(InitializeFirebase());
}
IEnumerator InitializeFirebase()
{
var dependencyTask = FirebaseApp.CheckAndFixDependenciesAsync();
yield return new WaitUntil(() => dependencyTask.IsCompleted);
var status = dependencyTask.Result;
if (status == DependencyStatus.Available)
{
FirebaseApp.DefaultInstance.Options.DatabaseUrl = new System.Uri("https://sibawa-81e2e-default-rtdb.asia-southeast1.firebasedatabase.app/");
isFirebaseReady = true;
Debug.Log("Firebase Ready");
}
else
{
Debug.LogError("Firebase Error: " + status);
}
}
public static bool IsConnectedToInternet()
{
return Application.internetReachability != NetworkReachability.NotReachable;
}
public static bool HasInternet => Application.internetReachability != NetworkReachability.NotReachable;
public static void SyncUserToFirebase(string kodeLogin, Action<bool> callback)
{
if (!IsConnectedToInternet())
{
callback?.Invoke(false);
return;
}
DatabaseReference dbRef = FirebaseDatabase.DefaultInstance.RootReference;
dbRef.Child("users").Child(kodeLogin).GetValueAsync().ContinueWithOnMainThread(task =>
{
if (task.IsCompleted && task.Result.Exists)
{
var snapshot = task.Result;
TestManager.Instance.username = snapshot.HasChild("username") ? snapshot.Child("username").Value.ToString() : "";
TestManager.Instance.pretestScore = snapshot.HasChild("pretest") ? int.Parse(snapshot.Child("pretest").Value.ToString()) : 0;
TestManager.Instance.posttestScore = snapshot.HasChild("posttest") ? int.Parse(snapshot.Child("posttest").Value.ToString()) : 0;
TestManager.Instance.kelas = snapshot.HasChild("kelas") ? snapshot.Child("kelas").Value.ToString() : "";
TestManager.Instance.absen = snapshot.HasChild("absen") ? snapshot.Child("absen").Value.ToString() : "";
callback?.Invoke(true);
}
else
{
Debug.LogWarning("Gagal sinkronisasi user ke TestManager.");
callback?.Invoke(false);
}
});
}
public static void CreateUser(string kodeLogin, string username, string kelas, string absen, Action<bool> cb)
{
if (!HasInternet)
{
cb(false);
return;
}
var data = new Dictionary<string, object>
{
{ "username", username },
{ "kelas", kelas },
{ "absen", absen },
{ "createdAt", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
{ "pretest", 0 },
{ "posttest", 0 }
};
FirebaseDatabase.DefaultInstance.RootReference
.Child("users").Child(kodeLogin)
.SetValueAsync(data)
.ContinueWithOnMainThread(t => cb(t.IsCompleted && t.Exception == null));
}
public static void SaveTestScore(string kodeLogin, int score, ShowingQuest.TestType type)
{
if (!IsConnectedToInternet()) return;
string field = type == ShowingQuest.TestType.Pretest ? "pretest" : "posttest";
DatabaseReference dbRef = FirebaseDatabase.DefaultInstance.RootReference;
dbRef.Child("users").Child(kodeLogin).Child(field).SetValueAsync(score).ContinueWithOnMainThread(task =>
{
if (task.IsCompleted)
Debug.Log("Score " + field + " disimpan untuk " + kodeLogin);
else
Debug.LogError("Gagal menyimpan skor: " + task.Exception);
});
}
public static void LoadUserTestScores(string kodeLogin, Action<int, int> callback)
{
DatabaseReference dbRef = FirebaseDatabase.DefaultInstance.RootReference;
dbRef.Child("users").Child(kodeLogin).GetValueAsync().ContinueWithOnMainThread(task =>
{
if (task.IsCompleted && task.Result.Exists)
{
var snapshot = task.Result;
int pre = snapshot.HasChild("pretest") ? int.Parse(snapshot.Child("pretest").Value.ToString()) : 0;
int post = snapshot.HasChild("posttest") ? int.Parse(snapshot.Child("posttest").Value.ToString()) : 0;
callback(pre, post);
}
else
{
Debug.LogWarning("Gagal mengambil skor dari Firebase.");
callback(0, 0);
}
});
}
public static void SaveUnlockedLevel(string kodeLogin, string materiName, int unlockedLevel)
{
if (!IsConnectedToInternet()) return;
FirebaseDatabase.DefaultInstance.RootReference
.Child("users").Child(kodeLogin).Child("progress").Child(materiName)
.SetValueAsync(unlockedLevel)
.ContinueWithOnMainThread(task =>
{
if (task.IsCompleted)
Debug.Log($"Level {unlockedLevel} untuk {materiName} disimpan ke Firebase");
else
Debug.LogError("Gagal menyimpan progress ke Firebase.");
});
}
public static void LoadLevelProgress(string kodeLogin, string materiName, Action<int> callback)
{
FirebaseDatabase.DefaultInstance
.GetReference("users")
.Child(kodeLogin)
.Child("progress")
.Child(materiName)
.GetValueAsync()
.ContinueWithOnMainThread(task =>
{
if (task.IsCompleted && task.Result.Exists)
{
int level = int.Parse(task.Result.Value.ToString());
callback(level);
}
else
{
callback(1); // default
}
});
}
public static void SavePosttestUnlocked(string kodeLogin, string materiName)
{
if (string.IsNullOrEmpty(kodeLogin) || string.IsNullOrEmpty(materiName)) return;
FirebaseDatabase.DefaultInstance
.GetReference("users")
.Child(kodeLogin)
.Child("posttestUnlocked")
.Child(materiName)
.SetValueAsync(true)
.ContinueWithOnMainThread(task =>
{
if (task.IsCompleted)
Debug.Log($"[DBManager] posttestUnlocked untuk '{materiName}' berhasil disimpan.");
else
Debug.LogError("[DBManager] Gagal menyimpan posttestUnlocked ke Firebase.");
});
}
public static void LoadPosttestUnlocked(string kodeLogin, string materiName, Action<bool> callback)
{
if (string.IsNullOrEmpty(kodeLogin) || string.IsNullOrEmpty(materiName))
{
Debug.LogWarning("[DBManager] LoadPosttestUnlocked: Parameter kosong.");
callback?.Invoke(false);
return;
}
FirebaseDatabase.DefaultInstance
.GetReference("users")
.Child(kodeLogin)
.Child("posttestUnlocked")
.Child(materiName)
.GetValueAsync()
.ContinueWithOnMainThread(task =>
{
if (task.IsFaulted || task.Result == null || !task.Result.Exists)
{
Debug.LogWarning($"[DBManager] posttestUnlocked '{materiName}' belum ada di Firebase.");
callback?.Invoke(false);
}
else
{
bool unlocked = task.Result.Value.ToString() == "True";
Debug.Log($"[DBManager] posttestUnlocked untuk '{materiName}' = {unlocked}");
callback?.Invoke(unlocked);
}
});
}
public static void GetUserData(string kodeLogin, Action<UserData> callback)
{
FirebaseDatabase.DefaultInstance
.GetReference("users")
.Child(kodeLogin)
.GetValueAsync()
.ContinueWithOnMainThread(task =>
{
if (task.IsCompleted && task.Result.Exists)
{
var snapshot = task.Result;
UserData data = new UserData
{
username = snapshot.Child("username").Value?.ToString(),
kelas = snapshot.Child("kelas").Value?.ToString(),
absen = snapshot.Child("absen").Value?.ToString(),
pretest = int.Parse(snapshot.Child("pretest").Value?.ToString() ?? "0"),
posttest = int.Parse(snapshot.Child("posttest").Value?.ToString() ?? "0")
};
callback?.Invoke(data);
}
else
{
Debug.LogError("[DBManager] Gagal memuat user data.");
callback?.Invoke(null);
}
});
}
}