Get it on Google Play


Wm뮤 :: 'FireBase' 카테고리의 글 목록

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

Recent Comment

Archive


2022. 4. 9. 11:28 FireBase

 

 

 

 

 

 

'FireBase' 카테고리의 다른 글

자주 쓰는 파이어베이스 RTDB 코드  (0) 2021.10.17
파이어 베이스 DB 보안  (0) 2021.10.16
파이어 베이스 오류모음  (0) 2021.10.11
posted by 모카쨩
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 모카쨩
2021. 10. 16. 20:21 FireBase

 

 

 

참고한곳

https://firebase.google.com/docs/database/security?hl=ko 

 

Firebase 실시간 데이터베이스 규칙 이해  |  Firebase Documentation

Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register 의견 보내기 Firebase 실시간 데이터베이스 규칙 이해 Firebase

firebase.google.com

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


using Firebase;
using Firebase.Database;
public class FireBaseDataBase : MonoBehaviour
{
    DatabaseReference reference ;
    public class User
    {
        public string username;
        public string email;

        public User(string username, string email)
        {
            this.username = username;
            this.email = email;
        }
    }
    public void WriteNewUser()
    {

        var auth = Firebase.Auth.FirebaseAuth.DefaultInstance;

        WriteNewUser(auth.CurrentUser.UserId, "test", "test@mail");//작동함
        WriteNewUser(auth.CurrentUser.UserId, "test2", "test2@mail");//작동함
        WriteNewUser("ABC"+(auth.CurrentUser.UserId).Substring("ABC".Length), "test2", "test2@mail");//작동함!!

    }
    private void WriteNewUser(string userId, string name, string email)
    {
        User user = new User(name, email);
        string json = JsonUtility.ToJson(user);

        reference.Child("users").Child(userId).SetRawJsonValueAsync(json);
    }
    // Start is called before the first frame update
    void Start()
    {
        reference = FirebaseDatabase.DefaultInstance.RootReference;

    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

 

상기와 같은 코드가 있다

 

 

이걸 그냥 쑤셔넣게 되면

 

 

 

 

 

 

 

자기 계정이 아닌데도 마음대로 값을 쓰고 수정해댄다

당연하다 저 계층값이 유저 ID인지 지역별 구분인지 이름인지 컴퓨터는 알수 없기 때문

따라서 저 계층은 uid와 동일할때만 값을 추가할수 있게 해달라고 할 것이다

 

 

 

 

 

 

 

열어보면 이렇게 되어있을것이다

11월 2일까지만 쓸 수 있댄다.

규칙을 바꿔주자

 

 

 

 

 

{
  "rules": 
  {
    "users": 
    {
      "$uid": 
      {
        ".write": "$uid === auth.uid",
        ".read": "$uid === auth.uid"
      }
    }
  }
}

uid가 동일해야만 읽고 쓸 수 있게 수정했다

이제 DB에 들어와서 아무나 난동부릴 수 없게됐다 Good

 

테스트 했던 유저값들은 지워주자

 

기본적으로 .write 규칙이 미정의된 부분은 쓰기 불가능이니 rules에 대한 룰은 지정 안 해주어도 될것이다

posted by 모카쨩
2021. 10. 11. 02:35 FireBase

 

 

SignInAnonymouslyAsync encountered an error

 

 

추가해라

 

 

---------------------------------------------------------------------------------------------

 

 

 

Assets\FirebaseConnectionSDK\IAPManager.cs(213,71): error CS0103: The name 'GooglePlayTangle' does not exist in the current context


Assets\FirebaseConnectionSDK\IAPManager.cs(213,96): error CS0103: The name 'AppleTangle' does not exist in the current context

 

플랫폼을 안드로이드로 바꾸면 사라진다

 

 

 

------------------------------------------------------------------------------

No GoogleService-Info.plist files found in your project. Building without Firebase configuration will result in an app that will fail to initialize.

 

plist안 넣어서 그렇다

 

 

받아서 넣는다

posted by 모카쨩
2021. 10. 5. 07:58 FireBase

 

 

Please fix your Bundle ID

패키지명이랑 인증서에 등록된 ID랑 달라서 그렇다

프로젝트 세팅에서 바꿔주자

 

 

 

 

 

 

 

 

 

 

Enable Android Auto-resolution?

안드로이드에서 레졸루션을 자동으로 활성화 하겠냐는 의미이다

보통은 가변 레졸루션을 쓰니까 Enable해주자

 

 

 

 

 

 

 

 

 

 

 

 

 

'FireBase' 카테고리의 다른 글

파이어 베이스 오류모음  (0) 2021.10.11
파이어 베이스 인증서 다운로드 받는법  (0) 2021.10.05
파이어 베이스 인증  (0) 2021.10.03
posted by 모카쨩
2021. 10. 5. 06:48 FireBase

 

 

 

 

 

여기 있다

'FireBase' 카테고리의 다른 글

파이어 베이스가 내뱉는 각종 메세지들 처리  (0) 2021.10.05
파이어 베이스 인증  (0) 2021.10.03
파이어베이스 DB 사용법  (0) 2021.10.03
posted by 모카쨩
2021. 10. 3. 11:10

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

2021. 10. 3. 07:00

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.


  • total
  • today
  • yesterday

Recent Post

저사양 유저용 블로그 진입