Scripting rookie here, so please bear with me.
- Working in Unity 2018
- Working with Google Firebase Storage + Authentication
During my authentication and subsequent acquisition of Asset Bundles, (stored remotely on our Google Firebase Storage setup) I've managed to correctly download proper, user-specific Bundles to a local location on my PC.
However, when switching gears and attempting to download/cache and STORE these Bundles in a variable via UnityWebRequest, I end up needing to provide my script double the initial prompting, otherwise it simply reaches this portion, and then considers itself finished or stalled with a lack of bugs/errors:
Prior to this point:
- User & Password are input and authenticated against on my Login Page (THIS IS THE INITIAL PROMPTING THAT IS SOMEHOW REQUIRED TWICE) via SignInWithEmailAndPasswordAsync.ContinueWith(task, etc)
- Firebase Storage Instance Created
- Firebase Personal File Structure Link Created
- Specific Bundles Are Referenced into Variables (prefab.ref is one such)
...and THEN there's this:
prefab_ref.GetDownloadUrlAsync().ContinueWith((Task<Uri> task1) => { if (!task1.IsFaulted && !task1.IsCanceled) { Debug.Log("Download URL: " + task1.Result); } prefabDL_URL = task1.Result; Debug.Log("Task1 Result got stored!"); });
After this point, post-Debug.Log, the script ceases, with no errors or issues. Once the Login button is pressed a SECOND time, the program continues, the Bundle is downloaded and stored, and the new Scene is loaded. I'd like to know how to force my program to push forward past this method, rather than having to push my Login button twice for no reason. Thanks in advance everyone!
My Full Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase.Auth;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;
using System.Threading.Tasks;
using UnityEngine.Networking;
public class EmailPasswordLogin : MonoBehaviour
{
private FirebaseAuth auth;
public InputField UserNameInput, PasswordInput;
public Button LoginButton;
public Text ErrorText;
public string uri;
public System.Uri prefabDL_URL;
public Firebase.Storage.StorageReference prefab_outerRef;
public Firebase.Storage.StorageReference vuforia_outerRef;
public AssetBundle prefabBndl;
public AssetBundle vuforiaBndl;
private void Start ()
{
//Establish instance of Firebase Authentication
auth = FirebaseAuth.DefaultInstance;
//Pre-fill the User/Password inputs for easy testing
UserNameInput.text = "MY USERNAME";
PasswordInput.text = "MY PASSWORD";
//Run the Login method when the LoginButton is pressed, taking the inputs
LoginButton.onClick.AddListener(() => Login(UserNameInput.text, PasswordInput.text));
}
//Our main method, takes in User and Password for Authentication and subsequent Bundle downloading
public void Login(string email, string password)
{
//Runs Firebase's Authentication Async-style, storing the result in a User variable and displaying this info to the Console
auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("SignInWithEmailAndPasswordAsync canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SignInWithEmailAndPasswordAsync error: " + task.Exception);
if (task.Exception.InnerExceptions.Count > 0)
{
UpdateErrorMessage(task.Exception.InnerExceptions[0].Message);
}
return;
}
FirebaseUser user = task.Result;
Debug.LogFormat("User signed in successfully: ({0}) ({1})", user.DisplayName, user.UserId);
PlayerPrefs.SetString("LoginUser", user != null ? user.Email : "Unknown");
//DOWNLOAD YOUR ASSET FILES RIGHT IN HERE\\
//Reference to ALL of Storage
Firebase.Storage.FirebaseStorage storage = Firebase.Storage.FirebaseStorage.DefaultInstance;
//Reference to my specific file under the current UserId
Firebase.Storage.StorageReference prefab_ref = storage.GetReferenceFromUrl("[FILE STRUCTURE PREFIX]" + user.UserId + "[FILE STRUCTURE SUFFIX]");
Firebase.Storage.StorageReference vuforia_ref = storage.GetReferenceFromUrl("[FILE STRUCTURE PREFIX]" + user.UserId + "[FILE STRUCTURE SUFFIX]");
//Store the specific file in a variable for use outside of the Method
prefab_outerRef = prefab_ref;
vuforia_outerRef = vuforia_ref;
//Acquire the URI for one specific file
prefab_ref.GetDownloadUrlAsync().ContinueWith((Task<Uri> task1) =>
{
if (!task1.IsFaulted && !task1.IsCanceled)
{
Debug.Log("Download URL: " + task1.Result);
}
prefabDL_URL = task1.Result;
Debug.Log("Task1 Result got stored!");
});
//Shoot this URI as a String to the Console, then run a Coroutine to acquire the Bundle from the URI
Debug.Log(prefabDL_URL.ToString());
StartCoroutine(GetBundle(prefabDL_URL));
//UnityWebRequestAssetBundle.GetAssetBundle(prefab_ref.ToString(), 1, 0);
//DOWNLOAD YOUR ASSET FILES RIGHT IN HERE\\
//Load the following scene once things are downloaded and stored
SceneManager.LoadScene("Main");
});
}
//Our Coroutine for acquring the actual bundle file, taking in the stored URI and using it to download via UnityWebRequestAssetBundle
IEnumerator GetBundle(Uri uri)
{
using (UnityWebRequest uwr = UnityWebRequestAssetBundle.GetAssetBundle(uri, 1, 0))
{
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || uwr.isHttpError)
{
Debug.Log(uwr.error);
}
else
{
//Get the content and store it in our pre-established Bundle variable, then talk to Console about it.
prefabBndl = DownloadHandlerAssetBundle.GetContent(uwr);
Debug.Log("We've got a bundle stored!");
}
}
}
//Update our Error Message
private void UpdateErrorMessage(string message)
{
ErrorText.text = message;
Invoke("ClearErrorMessage", 3);
}
//Blank out our Error Message
void ClearErrorMessage()
{
ErrorText.text = "";
}
}