bokob / Open_Start

충북대 컴퓨터공학과 실내 AR 네비게이션 앱 (창업경진대회)
1 stars 0 forks source link

Firebase For Unity #2

Open BiteSnail opened 2 years ago

BiteSnail commented 2 years ago

서버 만들어서 연결 해보겠습니다!

BiteSnail commented 2 years ago

Firebase storage에 연결해서 이미지 업로드 성공했습니다! 다만 제가 이미지 캡쳐하는 부분을 건드려서 좀 이상해 지긴 했는데 기본적인 틀은 완성된 것 같습니다. 아래는 업로드 완료 되었을 때 유니티 디버그 로그입니다. image

여러 가지 방법을 시도해 봤는데 어떤 것이 당첨 된 것인지 몰라서 확인 후에 다시 이슈 적겠습니다.

BiteSnail commented 2 years ago

방법을 찾은 것 같습니다! 우선 cloud storage에 보안 범위 설정을 하지 않았다는 가정하에 아래와 같은 방법으로 하면 되는 것 같습니다. 아래 코드는 업로드 테스트에 성공한 Firebase Cloud Storage의 Rules 입니다.

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write;
    }
  }
}

파일 업로드 에러 해결 방법 위 사이트에서 말하길 google-service.json 파일을 프로젝트 [Assets]->[StreamingAssets]에 넣으면 된다고 해서 그렇게 해결 완료 했습니다. image CoderZero20220810035337 테스트 결과 굉장히 잘 됩니다. 목요일에는 안드로이드 디바이스에 빌드해서 테스트 해보겠습니다. 아래 파일은 기존의 SaveScreenShot.cs에서 Local에 저장하는 부분을 Firebase Cloud Storage에 업로드 하는 부분으로 변경한 코드입니다.

ImageCommunication.cs

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Firebase.Storage;
using System.Threading.Tasks;
using Firebase.Extensions;

public class ImageCommunication : MonoBehaviour
{
    //gs://<your-cloud-storage-bucket>/<sub_path>/
    public string m_Path = "gs://<your-cloud-storage-bucket>/images/";
    public string m_FilePrefix = "Capture";   //fileName
    private string m_FilePath;

    public void UploadImage()
    {
        // Create a reference to the file you want to upload
        m_FilePath = m_Path + m_FilePrefix + DateTime.Now.ToString("yyyyMMddhhmmss") + ".jpg";
        StartCoroutine(SaveScreeJpg(m_FilePath));
    }

    IEnumerator SaveScreeJpg(string filePath)
    {
        yield return new WaitForEndOfFrame();

        // Start is called before the first frame update
        FirebaseStorage storage = FirebaseStorage.DefaultInstance;
        // Update is called once per frame
        StorageReference spaceRefFull = storage.GetReferenceFromUrl(filePath);

        Texture2D texture = new Texture2D(Screen.width, Screen.height / 2);
        texture.ReadPixels(new Rect(0, 750, Screen.width, Screen.height / 2), 0, 0);    // Rect(x축 시작 위치, y축 시작 위치)   // ReadPixels(원본, x축 어디, y축 어디)
        texture.Apply();

        // Data in memory
        byte[] bytes = texture.EncodeToJPG();   // jpg로 변환

        spaceRefFull.PutBytesAsync(bytes)
            .ContinueWith((Task<StorageMetadata> task) => {
                if (task.IsFaulted || task.IsCanceled) {
                    Debug.Log(task.Exception.ToString());
                    // Uh-oh, an error occurred!
                }
                else {
                    // Metadata contains file metadata such as size, content-type, and md5hash.
                    StorageMetadata metadata = task.Result;
                    string md5Hash = metadata.Md5Hash;
                    Debug.Log("Finished uploading...");
                    Debug.Log("md5 hash = " + md5Hash);
                }
            });

        DestroyImmediate(texture);
    }
}

p.s. Firebase SDK 설치 시 IOS XCode 관련해서 오류가 있었는데 무시해도 되는 거라고 하네요.

https://stackoverflow.com/questions/63374878/problem-on-unity-2020-and-firebase-unable-to-resolve-reference-unityeditor-ios

bokob commented 2 years ago

까비 목요일에 다시 해보려고 했는데 해결하셨네요. 고생하셨습니다.

bokob commented 2 years ago

갤러리 저장 방법: 1) https://gamedevplanet.com/how-to-take-a-screenshot-from-within-your-game-in-unity/ 2) https://stackoverflow.com/questions/60475027/unity-android-save-screenshot-in-gallery

이미지 업로드: https://www.youtube.com/watch?v=8yRsDLIaAIQ

내일 이거 한 번 도전해보겠습니다.

BiteSnail commented 2 years ago

firebase realtime database에 json파일 업로드 및 다운로드 기능을 추가할 수 있을 것 같습니다. 이를 이용해서 현재 위치 공유하기 기능 또한 새롭게 만들어 보겠습니다.

BiteSnail commented 2 years ago

Firebase RealTime DataBase에 현재 위치를 json파일로 올리는 코드입니다. firebase관련 스크립트들은 마지막에 올리기 위해서 이곳에 미리 적어둡니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase;
using Firebase.Database;
using Firebase.Extensions;

public class UploadLoc : MonoBehaviour
{

    //Target model json file
    [SerializeField]
    private TextAsset targetModelData;
    [SerializeField]
    private GameObject indicator;

    private DatabaseReference reference;

    // Start is called before the first frame update
    void Start()
    {
        // Get the root reference location of the database.
        reference = FirebaseDatabase.DefaultInstance.RootReference;
    }

    public void UploadLocation()
    {
        TargetWrapper tw = new TargetWrapper();
        tw.TargetList = new Target[]{ SaveLocationToTarget() };
        Debug.Log(JsonUtility.ToJson(tw));

        reference.SetRawJsonValueAsync(JsonUtility.ToJson(tw))
            .ContinueWithOnMainThread(task => {
                if(task.IsFaulted || task.IsCanceled){
                    //Handle to Error
                    Debug.Log("Failed to Upload Location");
                }
                else if(task.IsCompleted){
                    string hash = task.GetHashCode().ToString();
                    Debug.Log("Finished uploading...");
                    Debug.Log("md5 hash = " + hash);
                }
            });
    }
    private Target SaveLocationToTarget()
    {
        Target uploadLocation = new Target();
        uploadLocation.Name = "JH";
        uploadLocation.FloorNumber = (int)indicator.transform.position.y;
        uploadLocation.Position = indicator.transform.position;
        uploadLocation.Rotation = indicator.transform.rotation.eulerAngles;
        return uploadLocation;
    }
}

SaveLocationToTarget()함수에서 Name을 사용자 이름으로 바꾸면 여러명도 가능할 것 같습니다. 데이터 불러오는 것은 다음 시간에 해보겠습니다.