2021. 10. 17. 23:47
FireBase
uuid
var auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
var uuid = auth.CurrentUser.UserId;
레퍼런스
public static DatabaseReference DefaultReference
{
get
{
var reference = FirebaseDatabase.DefaultInstance.RootReference;
var auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
var userId = auth.CurrentUser.UserId;
return reference.Child("users").Child(userId);
}
}
저장
json타입
public void Save()
{
LocalReference.SetRawJsonValueAsync(JsonUtility.ToJson(this));
}
저장
리플렉션타입
public void Save()
{
foreach (var field in GetType().GetFields())
{
LocalReference.Child(field.Name).SetValueAsync(field.GetValue(this));
}
}
읽기
public static void Load(System.Action<User> successCallback)
{
LocalReference.GetValueAsync().ContinueWith(task =>
{
if (task.IsFaulted)
{
Debug.LogError("불러오는데 에러 발생");
successCallback.Invoke(null);
return;
// Handle the error...
}
if (task.IsCompleted==false)
{
Debug.LogError("불러오기 실패");
successCallback.Invoke(null);
return;
}
var snapshot = task.Result;
Debug.Log(snapshot.Value);
if (snapshot.Value == null)
{
Debug.LogError("데이터가 없음");
successCallback.Invoke(null);
return;
}
User user = new User(snapshot);
OnChangeUserEvent.Invoke(user);
Debug.Log("불러오기 성공");
// Do something with snapshot...
});
}
void Start()
{
User.Load(loadedUser =>
{
if (loadedUser!=null)
{
user = loadedUser;
}
OnChangeUserNameEvent.Invoke(user.username);
});
}
v2 (null반환을 위해 함수타입으로 바꿨다)
public static SaveData Load(DataSnapshot snapshot)
{
var json = snapshot.GetRawJsonValue();
Debug.Log("json:" + json);
if (json == null)
{
return null;
}
return JsonUtility.FromJson(json, typeof(SaveData)) as SaveData;
}
읽기 이벤트타입
void Start()
{
User.LocalReference.ValueChanged += HandleValueChanged;
}
void HandleValueChanged(object sender, ValueChangedEventArgs args)
{
if (args.DatabaseError != null)
{
Debug.LogError(args.DatabaseError.Message);
return;
}
var snapshot = args.Snapshot;
user = new User(snapshot);
OnChangeUserEvent.Invoke(user);
Debug.Log($"HandleValueChanged: {args.Snapshot.Value}");
// Do something with the data in args.Snapshot
}
읽기 트랜잭션 타입
public static SaveData Load(IEnumerable<DataSnapshot> childrens)
{
var snapshots = Enumerable.ToArray(childrens);
var saves = System.Array.ConvertAll(snapshots, snapshot => Load(snapshot));
return GetLastSave(saves);
}
snapshot To Class v1
public User(DataSnapshot snapshot)
{
foreach (var field in GetType().GetFields())
{
if (snapshot.HasChild(field.Name))
{
field.SetValue(this, snapshot.Child(field.Name).Value);
Debug.Log($"{field.Name}: {snapshot.Child(field.Name).Value}");
}
}
}
snapshot To Class v2
public User(DataSnapshot snapshot)
{
foreach (var item in snapshot.Children)
{
var field = GetType().GetField(item.Key);
if (field == null)
{
Debug.LogError($"{item.Key}가 존재하지 않음");
continue;
}
field.SetValue(this, item.Value);
Debug.Log($"{item.Key}:{item.Value}");
}
}
snapshot To Class v3
서버에 없는값은 null이 아니라 기본값으로 채워진다
public User(DataSnapshot snapshot)
{
var json = snapshot.GetRawJsonValue();
Debug.Log("json:" + json);
if (json == null)
{
return;
}
var snapshotUser = JsonUtility.FromJson(json, GetType());
foreach (var field in GetType().GetFields())
{
field.SetValue(this, field.GetValue(snapshotUser));
}
}
오프라인에서도 동작
조심해야할게 SetRawJsonValueAsync나 SetValueAsync를 날리면
불의의 사고로 데이터가 전부 롤백될수 있다는거다
(유저가 오프라인으로 플레이하던걸 방치하다가 폰을 교환하고 옛날폰을 다시 켠다던지)
이걸 쓰려면 중요정보는 무조건 트랜잭션으로 해야할것이다
FirebaseDatabase.DefaultInstance.SetPersistenceEnabled(true);
User.LocalReference.KeepSynced(true);
파이어베이스 서버시간 (lastOnlineTime)
로드가 먼저면 서버시간 불러오는단에서 추가하고, 아니면 로드쪽에서 갱신하도록 처리함
void Start()
{
SaveData.DefaultReference.ValueChanged += HandleValueChanged;
FirebaseDatabase.DefaultInstance.GetReference(".info/serverTimeOffset").ValueChanged += HandleServerTimeOffsetChanged;
}
void HandleValueChanged(object sender, ValueChangedEventArgs args)
{
if (args.DatabaseError != null)
{
Debug.LogError(args.DatabaseError.Message);
return;
}
var snapshot = args.Snapshot;
lock (saveData)
{
saveData = new SaveData(snapshot);
if (lastOnlineTime!=0)
{
saveData.lastOnlineTime = lastOnlineTime;
}
}
Debug.Log($"HandleValueChanged: {args.Snapshot.Value}");
// Do something with the data in args.Snapshot
}
long lastOnlineTime = 0;
void HandleServerTimeOffsetChanged(object sender, ValueChangedEventArgs args)
{
Debug.Log($"Offset: {args.Snapshot.Value}");
lastOnlineTime= System.DateTime.UtcNow.Ticks + (long)args.Snapshot.Value * 10000;
if (saveData!=null)
{
lock (saveData)
{
saveData.lastOnlineTime = lastOnlineTime;
saveData.Save();
}
}
}
'FireBase' 카테고리의 다른 글
파이어 스토리지 (0) | 2022.04.09 |
---|---|
파이어 베이스 DB 보안 (0) | 2021.10.16 |
파이어 베이스 오류모음 (0) | 2021.10.11 |