For a comprehensive guide on integrating Firebase with Unity, developers are encouraged to consult the official Firebase documentation. What follows in this tutorial is a concise overview tailored to our specific use case.
The highlighted part in the following image is the folder location where we will upload the anchor file.
Upload/download files
We've developed a dedicated FirebaseStorageManager class to facilitate file upload and download functionalities. For detailed implementation, you can refer to the official documentation.
It's important to note that whether you're uploading or downloading, the storagePath should include the specific filename, not just the directory. This specification is also highlighted in the documentation.
Therefore, We set the file path obtained from the previous step as storageBasePath and later concatenate it with the filename to form the complete path for upload/download.
usingFirebase;usingFirebase.Extensions;usingFirebase.Storage;usingSystem;usingSystem.IO;usingSystem.Threading;usingSystem.Threading.Tasks;usingUnityEngine;publicclassFirebaseStorageManager:MonoBehaviour{publicstaticFirebaseStorageManager Instance { get; privateset; }publicstring storageBasePath ="gs://YourProjectName-xxxxxx.appspot.com/";privateFirebaseStorage storage;privateCancellationTokenSource cancellationTokenSource;privatebool operationInProgress =false;publicconststring MapFolder ="XrealMaps";voidStart() {FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {FirebaseApp.Create(); storage =FirebaseStorage.DefaultInstance; cancellationTokenSource =newCancellationTokenSource(); });if (Instance ==null) { Instance =this; DontDestroyOnLoad(gameObject); // Optional, if you want this instance to be preserved during scene transitions.
}else {Destroy(gameObject); // } }publicTaskUploadFile(string fileName,string localFilePath){string localFile = localFilePath;string storagePath =Path.Combine(storageBasePath, fileName); // Check if the file exists.if (!File.Exists(localFile)) {Debug.LogError($"File {localFile} does not exist!");returnTask.CompletedTask; // If the file does not exist, return a completed task. }else {Debug.Log($"File {localFile} exist!"); }StorageReference storageRef =storage.GetReferenceFromUrl(storagePath);Debug.Log($"Uploading {localFile} to {storagePath}..."); // Create a stream using FileStream.Stream fileStream =newFileStream(localFile,FileMode.Open); // Create a TaskCompletionSource to identify when the task is completed.TaskCompletionSource<bool> tcs =newTaskCompletionSource<bool>(); // Use PutStreamAsync to upload the stream.storageRef.PutStreamAsync(fileStream).ContinueWithOnMainThread(task => {if (task.IsFaulted||task.IsCanceled) {Debug.LogError(task.Exception.ToString());tcs.SetResult(false); // Set the task as completed, but return failure. }else {Debug.Log("File uploaded successfully.");tcs.SetResult(true); // Set the task to be completed successfully. } });returntcs.Task;}publicTaskDownloadFile(string fileName,string localFilePath){string localFile = localFilePath;string storagePath =Path.Combine(storageBasePath, fileName);StorageReference storageRef =storage.GetReferenceFromUrl(storagePath);Debug.Log($"Downloading {storagePath} to {localFile}...");TaskCompletionSource<bool> tcs =newTaskCompletionSource<bool>();storageRef.GetFileAsync(localFile,newStorageProgress<DownloadState>(state => {Debug.Log($"Downloading {state.BytesTransferred} of {state.TotalByteCount} bytes."); }),cancellationTokenSource.Token).ContinueWithOnMainThread(task => {if (task.IsFaulted||task.IsCanceled) {Debug.LogError(task.Exception.ToString());tcs.SetResult(false); }else {Debug.Log("File downloaded successfully.");tcs.SetResult(true); } });returntcs.Task;}publicvoidCancelOperation() {if (operationInProgress && cancellationTokenSource !=null) {Debug.Log("Cancelling operation...");cancellationTokenSource.Cancel(); cancellationTokenSource =newCancellationTokenSource(); } }}
Common Issues
After installing Firebase, building software in Unity may fail. This is a known issue with Android and requires adding launcherTemplate.gradle in Unity, then adding the following content: