Get it on Google Play


Wm뮤 :: 자주 쓰는 파이어베이스 RTDB 코드

블로그 이미지
가끔 그림그리거나 3D모델링하거나
취미로 로봇만드는
퇴직한 전자과 게임프로그래머
2020.3.48f1 , 2022.3.6f1 주로 사용
모카쨩
@Ahzkwid

Recent Comment

Archive


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
posted by 모카쨩

  • total
  • today
  • yesterday

Recent Post

저사양 유저용 블로그 진입