LoginSignup
5
7

More than 5 years have passed since last update.

Firebaseのストレージアクセス

Last updated at Posted at 2017-06-04

環境

Unity5.6.1f1
firebase_unity_sdk_3.0.3

認証等のコンソール設定を済ませてある状態
Firebaseの匿名認証(Android)

概要

テクスチャのデータを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でも毎回アカウントが変わるようにしてあります。

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
    }
}
5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7