Firebaseのストレージアクセス

#環境
Unity5.6.1f1
firebase_unity_sdk_3.0.3

認証等のコンソール設定を済ませてある状態
<a href=http://qiita.com/fukaken5050/items/c615d8102e8499b123d4 >Firebaseの匿名認証(Android)</a>

#概要
テクスチャのデータをPNG化し、ストレージに保存、取得します

#コンソールの設定
・以下にアクセスし、作成済みのプロジェクトを開く（例:TestFirebase2）
　https://console.firebase.google.com/
・左側メニューの「Storage」を押す
・「GET　STARTED」を押す
　「gs://your-firebase-storage-bucket」が確認できる（例：gs://testfirebase2-bc737.appspot.com）

##エディタ用のルール設定
・エディタ用にサービスアカウントを設定しても、認証が通らなかった為、仕方ないので公開設定にする
・Android実機のみで動作させる場合は必要ない

・上部にある「ルール」を選択
・//を追加して公開状態にする
　allow read, write//: if request.auth != null;

#Unityエディタの設定
・Unityプロジェクトを起動する（例:TestFirebase2）
・SDKをダウンロードする
　・https://firebase.google.com/docs/unity/setup
・zip内に含まれている「FirebaseStorage.unitypackage」をインポートする

#プログラム
Signout()を最初に実行することで、Androidでも毎回アカウントが変わるようにしてあります。

```csharp
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Firebase;
using Firebase.Unity.Editor;
using Firebase.Auth;
using Firebase.Database;
using Firebase.Storage;
using System.Collections;
using System;

//typedef
using UnityObject = UnityEngine.Object;
using UnityRandom = UnityEngine.Random;

public class TestFirebase : MonoBehaviour
{
	[SerializeField] private Text _textUserData = null;
	[SerializeField] private ScrollRect _scrollRectUserData = null;
	[SerializeField] private GameObject _listItemUserDataPrefab = null;

	private FirebaseAuth _auth = null;
	private DatabaseReference _databaseReference = null;
	private StorageReference _storageReference = null;

	private IEnumerator Start()
	{
		FirebaseApp.DefaultInstance.SetEditorDatabaseUrl( "https://testfirebase2-bc737.firebaseio.com/" );
		FirebaseApp.DefaultInstance.SetEditorP12FileName( "TestFirebase2-3e858070b1cd.p12");
		FirebaseApp.DefaultInstance.SetEditorServiceAccountEmail( "unityeditor@testfirebase2-bc737.iam.gserviceaccount.com" );
		FirebaseApp.DefaultInstance.SetEditorP12Password( "notasecret" );
		FirebaseApp.DefaultInstance.SetEditorAuthUserId( "UnityEditor" );

		_auth =FirebaseAuth.GetAuth( FirebaseApp.DefaultInstance );//FirebaseAuth.DefaultInstance;
		_auth.StateChanged += OnAuthStateChanged;
		_databaseReference = FirebaseDatabase.DefaultInstance.RootReference;
		_storageReference = FirebaseStorage.DefaultInstance.GetReferenceFromUrl( "gs://testfirebase2-bc737.appspot.com" );

		Signout();
		yield return null;
	}

	private void OnApplicationQuit()
	{
		OnDestroy();		
	}

	private void OnDestroy()
	{
		_auth.StateChanged -= OnAuthStateChanged;
	}

	private void OnAuthStateChanged( object sender, EventArgs eventArgs )
	{
		Debug.Log( "OnAuthStateChanged" );
		if( _auth.CurrentUser != null )
		{
		}
	}

	private void Signout()
	{
		Debug.Log( "Signout" );

		var user = _auth.CurrentUser;
		if( user != null )
		{
			_auth.SignOut();
			Debug.Log( "DeleteAsync" );
			user.DeleteAsync().ContinueWith( task =>
			{
				if( task.IsCanceled == true )
				{
					Debug.Log( "Canceled" );
				}
				else if( task.IsFaulted == true )
				{
					Debug.Log( "Faulted" );
					Signin();
				}
				else if ( task.IsCompleted == true )
				{
					Debug.Log( "Completed" );
					Signin();
				}
			});
		}
		else
			Signin();
	}

	private void Signin()
	{
		Debug.Log( "Signin" );

		var  user = _auth.CurrentUser;
		if( user == null )
		{
			Debug.Log( "SignInAnonymouslyAsync" );
			_auth.SignInAnonymouslyAsync().ContinueWith( task =>
			{
				if( task.IsCanceled == true )
				{
					Debug.Log( "Canceled" );
				}
				else if( task.IsFaulted == true )
				{
					Debug.Log( "Faulted" );
				}
				else if ( task.IsCompleted == true )
				{
					Debug.Log( "Completed" );
					FirebaseUser newUser = task.Result;
					CreateUser( newUser );
				}
			});
		}
		else
		{
			OnSignin();
		}
	}

	private void CreateUser( FirebaseUser newUser )
	{
		Debug.Log( "OnCreateUser" );
		var  user = _auth.CurrentUser;
		if( user.GetUserId() != newUser.GetUserId() )
			Debug.LogError( user.GetUserId() + "/" + newUser.GetUserId() );

		//ユーザーデータがすでにあるかチェック
		_databaseReference.Child( "userDatas" ).Child( newUser.GetUserId() ).GetValueAsync().ContinueWith( task =>
		{
			Debug.Log( "GetValueAsync" );
			if ( task.IsFaulted == true || task.Result.Exists == false )
			{
				Debug.Log( "Faulted" );
				//通常こっち
				CreateUserData( newUser, OnSignin );
			}
			else if ( task.IsCompleted == true )
			{
				Debug.Log( "Completed" );
#if UNITY_EDITOR
				OnSignin();
#else
				Debug.LogError( "Error! UserData" );
#endif
			}
		});
	}

	private void CreateUserData( FirebaseUser newUser, UnityAction onResult )
	{
		//ユーザーデータ作成
		UserData userData = new UserData();
		userData.userId = newUser.GetUserId();
		userData.score = UnityRandom.Range( 0, int.MaxValue );
		string json = JsonUtility.ToJson( userData );

		_databaseReference.Child( "userDatas" ).Child( newUser.GetUserId() ).SetRawJsonValueAsync( json ).ContinueWith( task =>
		{
			Debug.Log( "OnCreateUserData" );
			if ( task.IsFaulted == true )
			{
				Debug.Log( "Faulted" );
			}
			else if ( task.IsCompleted == true )
			{
				Debug.Log( "Completed" );

				CreateUserImage( onResult );
			}
		});
	}

	private void OnSignin()
	{
		Debug.Log( "OnSignin" );

		var user = _auth.CurrentUser;
		Debug.Log( user.DisplayName + ":" + user.GetUserId() );

		if( _textUserData != null )
			_textUserData.text = user.DisplayName + "/" + user.GetUserId();

		//ユーザーデータリスト取得
		GetUserDatas();
	}

	private void GetUserDatas()
	{
		Debug.Log( "GetUserDatas" );

		if( _scrollRectUserData != null )
		{
			var content = _scrollRectUserData.content;
			for( int i = 0; i < content.childCount; i++ )
			{
				var child = content.GetChild( i );
				DestroyObject( child );
			}
			content.DetachChildren();
			_listItemUserDataPrefab.SetActive( false );
		}

		_databaseReference.Child( "userDatas" ).GetValueAsync().ContinueWith( task =>
		{
			Debug.Log( "OnGetUserDatas" );
			if ( task.IsFaulted == true )
			{
				Debug.Log( "Faulted" );
			}
			else if ( task.IsCompleted == true )
			{
				DataSnapshot snapshot = task.Result;
				Debug.Log( snapshot.ToString() );
				foreach( var child in snapshot.Children )
				{
					var userData = JsonUtility.FromJson<UserData>( child.GetRawJsonValue() );
					Debug.Log( "Key:" + child.Key + "/" + userData.ToString() );

					GameObject item = null;
					if( _scrollRectUserData != null )
					{
						var content = _scrollRectUserData.content;
						item = Instantiate<GameObject>( _listItemUserDataPrefab );
						item.GetComponentInChildren<Text>().text = userData.userId + "\n" + userData.score;
						item.SetActive( true );
						item.transform.SetParent( content, false );

						var user = _auth.CurrentUser;
						if( userData.userId == user.GetUserId() )
						{
							var image = item.GetComponent<Image>();
							image.color = Color.green;
						}
					}
					GetUserImage( userData.userId, item );
				}
			}
		});
	}
	//----------------------------------------------------------------------------
	//ストレージ
	//----------------------------------------------------------------------------
	private void CreateUserImage( UnityAction onResult )
	{
		Debug.Log( "CreateUserImage" );
		var user = _auth.CurrentUser;
		if( user == null )
			return;
		var imageRef = _storageReference.Child( "images/" + user.GetUserId() + ".png" );

		var texture = new Texture2D( 64, 64, TextureFormat.ARGB32, false );
		var colors = new Color32[ 64 * 64 ];
		var color = new Color32( (byte)UnityRandom.Range( 0, 256 ), (byte)UnityRandom.Range( 0, 256 ), (byte)UnityRandom.Range( 0, 256 ), 255 );
		for( int y = 0; y < 64; y++ )
			for( int x = 0; x < 64; x++ )
				colors[ ( y * 64 ) + x ] = color;

		texture.SetPixels32( colors );
		var pngBytes = texture.EncodeToPNG();

		Debug.Log( "PutBytesAsync" );
		imageRef.PutBytesAsync( pngBytes ).ContinueWith( task =>
		{
			if ( task.IsFaulted == true || task.IsCanceled == true )
			{
				Debug.Log( task.Exception.ToString() );
			}
			else
			{
				StorageMetadata metadata = task.Result;
				var downloadUrl = metadata.DownloadUrl;
				Debug.Log("downloadUrl = " + downloadUrl );

				if( onResult != null )
					onResult.Invoke();
			}

		});
	}

	private void GetUserImage( string userId, GameObject item )
	{
		var imageRef =  _storageReference.Child( "images/" + userId + ".png" );

		const long maxDownloadSize = 64 * 1024; //64k
		imageRef.GetBytesAsync( maxDownloadSize ).ContinueWith( task =>
		{
			if ( task.IsFaulted == true || task.IsCanceled == true )
				Debug.Log( task.Exception.ToString() );
			else
			{
				var pngBytes = task.Result;
				var texture = new Texture2D( 64, 64, TextureFormat.ARGB32, false );
				texture.LoadImage( pngBytes );
				if( item != null )
				{
					var rawImage = item.GetComponentInChildren<RawImage>();
					rawImage.texture = texture;
				}
			}
        });
	}
}

public static class FirebaseExtensions
{
	public static string GetUserId( this FirebaseUser user )
	{
//#if UNITY_EDITOR
//		return "UnityEditor";
//#else
		return user.UserId;
//#endif
	}
}
```