[SKKU DT] 33일차 -유니티 네트워크 -파이어베이스(Firebase) Firestore 예제

2023. 12. 14. 18:22SKKU DT

728x90
반응형

FireStore Database 예제

using Firebase;
using Firebase.Firestore;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyExample : MonoBehaviour
{
    private FirebaseFirestore db;
    private void Start()
    {
        FirebaseApp app = FirebaseApp.DefaultInstance;
        db = FirebaseFirestore.DefaultInstance;
    }
    public void AddData()
    {
        DocumentReference docRef = db.Collection("MyBoard").Document("MyInfo");
        Dictionary<string, object> user = new Dictionary<string, object>
        {
            {"data_1", 1 },
            {"data_2", 1 },
            {"data_3", 1 },
            {"data_4", 1 },
            {"data_5", 1 },
            {"Longdata_1", 10 },
            {"Longdata_2", 10 },
            {"Longdata_3", 10 },
            {"Longdata_4", 10 },
            {"Longdata_5", 10 },
        };

        docRef.SetAsync(user).ContinueWith(task =>
        {
            if(task.IsFaulted)
            {
                Debug.Log("Failed");
            }
            if(task.IsCompleted)
            {
                Debug.Log("Completed");
            }
        });
    }
}

 

 

버튼을 만든 후 AddData() 함수를 매핑한다. 버튼을 눌러 Completed가 뜨면 Firestore에서 내용을 확인할 수 있다.

 

 


 

 

1초마다 위의 데이터를 랜덤한 값으로 변경하기

private void Start()
{
    FirebaseApp app = FirebaseApp.DefaultInstance;
    db = FirebaseFirestore.DefaultInstance;
    InvokeRepeating("UpdateRandomData", 1.0f, 1.0f); //정해진 함수를 얼마시간 동안 반복할건지. 여기서는 1초마다
}
public void UpdateRandomData()
{
    DocumentReference docRef = db.Collection("MyBoard").Document("MyInfo");

    Dictionary<string, object> randomData = new Dictionary<string, object>
    {
        {"data_1", Random.Range(1, 11) },
        {"data_2", Random.Range(1, 11) },
        {"data_3", Random.Range(1, 11) },
        {"data_4", Random.Range(1, 11) },
        {"data_5", Random.Range(1, 11) },
        {"Longdata_1", Random.Range(1, 101) },
        {"Longdata_2", Random.Range(1, 101) },
        {"Longdata_3", Random.Range(1, 101) },
        {"Longdata_4", Random.Range(1, 101) },
        {"Longdata_5", Random.Range(1, 101) }
    };
    docRef.UpdateAsync(randomData).ContinueWith(task =>
    {
        if (task.IsCompleted)
        {
            Debug.Log("Document updated!");
        }
        else
        {
            Debug.LogError("Failed: " + task.Exception);
        }
    });
}

Start 함수에 InvokeRepeating으로 아래의 함수 UpdateRandomData를 1초 주기로 업데이트 한다.

업데이트가 잘 되는 것을 볼 수 있다.

 

 

함수를 분리해서 초를 다르게 설정하면 다르게 작동하는 것도 볼 수 있다.

using Firebase;
using Firebase.Firestore;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyExample : MonoBehaviour
{
    private FirebaseFirestore db;
    private void Start()
    {
        FirebaseApp app = FirebaseApp.DefaultInstance;
        db = FirebaseFirestore.DefaultInstance;
        InvokeRepeating("UpdateRandomData", 1.0f, 1.0f); //정해진 함수를 얼마시간 동안 반복할건지. 여기서는 1초마다
        InvokeRepeating("UpdateRandomDataFiveSecond", 5.0f, 5.0f);
    }
    public void AddData()
    {
        DocumentReference docRef = db.Collection("MyBoard").Document("MyInfo");
        Dictionary<string, object> user = new Dictionary<string, object>
        {
            {"data_1", 1 },
            {"data_2", 1 },
            {"data_3", 1 },
            {"data_4", 1 },
            {"data_5", 1 },
            {"Longdata_1", 10 },
            {"Longdata_2", 10 },
            {"Longdata_3", 10 },
            {"Longdata_4", 10 },
            {"Longdata_5", 10 }
        };

        docRef.SetAsync(user).ContinueWith(task =>
        {
            if(task.IsFaulted)
            {
                Debug.Log("Failed");
            }
            if(task.IsCompleted)
            {
                Debug.Log("Completed");
            }
        });
    }

    public void UpdateRandomData()
    {
        DocumentReference docRef = db.Collection("MyBoard").Document("MyInfo");

        Dictionary<string, object> randomData = new Dictionary<string, object>
        {
            {"data_1", Random.Range(1, 11) },
            {"data_2", Random.Range(1, 11) },
            {"data_3", Random.Range(1, 11) },
            {"data_4", Random.Range(1, 11) },
            {"data_5", Random.Range(1, 11) }
        };
        docRef.UpdateAsync(randomData).ContinueWith(task =>
        {
            if (task.IsCompleted)
            {
                Debug.Log("Document updated!");
            }
            else
            {
                Debug.LogError("Failed: " + task.Exception);
            }
        });
    }
    public void UpdateRandomDataFiveSecond()
    {
        DocumentReference docRef = db.Collection("MyBoard").Document("MyInfo");

        Dictionary<string, object> randomData = new Dictionary<string, object>
        {
            {"Longdata_1", Random.Range(1, 101) },
            {"Longdata_2", Random.Range(1, 101) },
            {"Longdata_3", Random.Range(1, 101) },
            {"Longdata_4", Random.Range(1, 101) },
            {"Longdata_5", Random.Range(1, 101) }
        };
        docRef.UpdateAsync(randomData).ContinueWith(task =>
        {
            if (task.IsCompleted)
            {
                Debug.Log("Document updated!");
            }
            else
            {
                Debug.LogError("Failed: " + task.Exception);
            }
        });
    }
}

 

 


 

 

StorageUploader 스크립트 생성

using Firebase.Extensions;
using Firebase.Storage;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class StorageUploader : MonoBehaviour
{
    FirebaseStorage storage;
    public TMP_InputField localFilePath;
    public TMP_InputField storagePath;

    private void Start()
    {
        storage = FirebaseStorage.DefaultInstance;
    }

    public void UploadFile()
    {
        string LocalFilePath = localFilePath.text;
        string StoragePath = storagePath.text;
        StorageReference storageRef = storage.GetReference(StoragePath);

        storageRef.PutFileAsync(LocalFilePath).ContinueWithOnMainThread(task =>
        {
            if(task.IsFaulted)
            {
                Debug.Log("Fault");
            }
            else
            {
                Debug.Log("Yes");
            }
        });
    }
}

 

함수를 버튼에 매핑하고 실행하면, URL에 있는 해당 파일을 Firebase Storage에 올릴 수 있다.

 

Storage에 잘 올라간 것을 볼 수 있다.

 

 


 

 

업로드 후 다운로드 URL까지 같이 출력되는 스크립트

using Firebase.Extensions;
using Firebase.Storage;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class StorageUploader : MonoBehaviour
{
    FirebaseStorage storage;
    public TMP_InputField localFilePath;
    public TMP_InputField storagePath;

    private void Start()
    {
        storage = FirebaseStorage.DefaultInstance;
    }

    public void UploadFile()
    {
        string LocalFilePath = localFilePath.text;
        string StoragePath = storagePath.text;
        StorageReference storageRef = storage.GetReference(StoragePath);

        storageRef.PutFileAsync(LocalFilePath).ContinueWithOnMainThread(task =>
        {
            if(task.IsFaulted)
            {
                Debug.Log("Fault");
            }
            else
            {
                Debug.Log("Yes");
                GetDownloadUrl(storageRef);
            }
        });
    }

    private void GetDownloadUrl(StorageReference storageRef)
    {
        storageRef.GetDownloadUrlAsync().ContinueWithOnMainThread(task =>
        {
            if (task.IsFaulted || task.IsCanceled)
            {
                Debug.Log("URL Fault");
            }
            else
            {
                string downloadURL = task.Result.ToString();
                Debug.Log("downloadURL : " + downloadURL);
            }
        });
    }
}

 

 


 

 

업로드한 이미지 받아오기

public RawImage displayImage;

 

코루틴 생성

private void GetDownloadUrl(StorageReference storageRef)
{
    storageRef.GetDownloadUrlAsync().ContinueWithOnMainThread(task =>
    {
        if (task.IsFaulted || task.IsCanceled)
        {
            Debug.Log("URL Fault");
        }
        else
        {
            string downloadURL = task.Result.ToString();
            Debug.Log("downloadURL : " + downloadURL);
            StartCoroutine(DownloadImage(downloadURL));
        }
    });
}

IEnumerator DownloadImage(string url)
{
    UnityWebRequest request = UnityWebRequestTexture.GetTexture(url);
    yield return request.SendWebRequest();
    if(request.result != UnityWebRequest.Result.Success)
    {
        Debug.LogError("Error download image: " + request.error);
    }
    else
    {
        Texture2D downTexture = DownloadHandlerTexture.GetContent(request);
        displayImage.texture = downTexture;
    }
}

 

전체 코드

using Firebase.Extensions;
using Firebase.Storage;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class StorageUploader : MonoBehaviour
{
    FirebaseStorage storage;
    public TMP_InputField localFilePath;
    public TMP_InputField storagePath;
    public RawImage displayImage;

    private void Start()
    {
        storage = FirebaseStorage.DefaultInstance;
    }

    public void UploadFile()
    {
        string LocalFilePath = localFilePath.text;
        string StoragePath = storagePath.text;
        StorageReference storageRef = storage.GetReference(StoragePath);

        storageRef.PutFileAsync(LocalFilePath).ContinueWithOnMainThread(task =>
        {
            if(task.IsFaulted)
            {
                Debug.Log("Fault");
            }
            else
            {
                Debug.Log("Yes");
                GetDownloadUrl(storageRef);
            }
        });
    }

    private void GetDownloadUrl(StorageReference storageRef)
    {
        storageRef.GetDownloadUrlAsync().ContinueWithOnMainThread(task =>
        {
            if (task.IsFaulted || task.IsCanceled)
            {
                Debug.Log("URL Fault");
            }
            else
            {
                string downloadURL = task.Result.ToString();
                Debug.Log("downloadURL : " + downloadURL);
                StartCoroutine(DownloadImage(downloadURL));
            }
        });
    }

    IEnumerator DownloadImage(string url)
    {
        UnityWebRequest request = UnityWebRequestTexture.GetTexture(url);
        yield return request.SendWebRequest();
        if(request.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError("Error download image: " + request.error);
        }
        else
        {
            Texture2D downTexture = DownloadHandlerTexture.GetContent(request);
            displayImage.texture = downTexture;
        }
    }
}

 

이미지를 올리고 해당 이미지를 Raw Image에 표시까지 되게 했다.

 

 


 

 

Firestore와 Firebase Storage를 동시에 사용

using Firebase.Extensions;
using Firebase.Firestore;
using Firebase.Storage;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class FirestoreUploadData : MonoBehaviour
{
    FirebaseStorage storage;
    FirebaseFirestore db;
    public TMP_InputField localFilePath;
    public TMP_InputField storagePath;

    private void Start()
    {
        //초기화
        storage = FirebaseStorage.DefaultInstance;
        db = FirebaseFirestore.DefaultInstance;
    }

    public void UploadFile()
    {
        string LocalFilePath = localFilePath.text;
        string StoragePath = storagePath.text;

        StorageReference storageRef = storage.GetReference(StoragePath);

        storageRef.PutFileAsync(LocalFilePath).ContinueWithOnMainThread(task =>
        {
            if(task.IsCompleted)
            {
                Debug.Log("File upload Successfully");
                GetDownloadURL(storageRef);
            }
            else
            {
                Debug.Log("File upload failed");
            }
        });
    }
    private void GetDownloadURL(StorageReference storageRef)
    {
        storageRef.GetDownloadUrlAsync().ContinueWithOnMainThread(task =>
        {
            if (task.IsCompleted)
            {
                Debug.Log("getting url seccesfully");
                string downloadURL = task.Result.ToString();
                SaveToFirestore(downloadURL);
            }
            else
            {
                Debug.Log("getting url failed");
            }
        });
    }
    private void SaveToFirestore(string downloadURL)
    {
        var imageData = new Dictionary<string, object>
        {
            {"url", downloadURL },
            {"timestamp", FieldValue.ServerTimestamp }
        };

        db.Collection("UpImage").AddAsync(imageData).ContinueWithOnMainThread(task =>
        {
            if (task.IsCompleted)
            {
                Debug.Log("Image data saved to firestore successfully");
            }
            else
            {
                Debug.Log("failed to saved image data to firestore");
            }
        });
    }
}

 

 


 

 

이미지 10장을 불러오게 하기

이미지를 10장 준비한다.

 

다음과 같은 스크립트를 작성한다.

using Firebase.Storage;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StorageSequenceImage : MonoBehaviour
{
    FirebaseStorage storage;
    List<string> localImagePath;
    string folderPathInStorage = "CCTV";
    private void Start()
    {
        storage = FirebaseStorage.DefaultInstance;
        localImagePath = new List<string>();

        for(int i = 1; i <= 10; i++)
        {
            localImagePath.Add("C:/tmp/Sequence/1701264329720_" + i.ToString("D2") + ".jpg"); //파일 명 뒤에 숫자가 하나씩 붙는다.
        }
        StartCoroutine(UploadSequenceImage());
    }

    IEnumerator UploadSequenceImage()
    {
        foreach(var imagepath in localImagePath)
        {
            yield return UploadImage(imagepath);
        }
    }

    IEnumerator UploadImage(string localpath)
    {
        string fileName = System.IO.Path.GetFileName(localpath);
        string stroagePath = folderPathInStorage + "/" + fileName;

        StorageReference storageRef = storage.GetReference(stroagePath);
        var task = storageRef.PutFileAsync(localpath);

        yield return new WaitUntil(() => task.IsCompleted);
        if(task.IsFaulted || task.IsCanceled)
        {
            Debug.Log("Failed");
        }
        else
        {
            Debug.Log("Success");
        }
    }
}

 

실행하면 Success 출력이 되고,

 

CCTV라는 폴더 안에 잘 들어간 것을 볼 수 있다.

728x90
반응형