Firebaseの匿名認証(Android)

#環境
Unity5.6.1f1
firebase_unity_sdk_3.0.3

#概要
Firebaseに匿名認証でアクセスし、データベースにユーザーデータを保存、取得します

#Firebaseコンソールの設定
https://console.firebase.google.com/

##Androidの設定
・「プロジェクトの追加」を押し、プロジェクトを作成する
　・プロジェクト名と国を設定（例：Testfirebase2, 日本）
　・testfirebase2-bc737となった
・「Android アプリに Firebase を追加」を押す
　・Android パッケージ名を入れる（例：com.example.testfirebase2）
　・アプリの登録を押す
　・「ダウンロードgoogle_services.json」でjsonを保存する
　・続行を押す
　・終了を押す

##匿名認証の設定
・左側のメニューの「Authentication」を押す
・上側にある「ログイン方法」を押す
・「匿名」を押し、「有効にする」をONにして保存する

##エディタ用の権限の追加
・左側のメニューの「Overview」の横の歯車アイコンを押し、「権限」を押す
・左側のメニューの「サービスアカウント」を押す
・上側にある「サービスアカウントを作成」を押す
　・「サービスアカウント名」を設定（例：UnityEditor）
　・「役割」をProject>オーナーに設定
　・「新しい秘密鍵の提供」にチェック 
　　・「キーのタイプ」をP12にする
　・作成を押す
　　・p12ファイルが自動的にパソコンに保存され、ダイアログにパスワードが表示される

#Unityプロジェクトの設定
・Unityを起動し、プロジェクトを作成する（例：TestFirebase2）
　・Androidにスイッチし、バンドルIdをコンソールで設定したものにする（例：com.example.testfirebase2）
・SDKをダウンロードする
　・https://firebase.google.com/docs/unity/setup
・zip内に含まれている「FirebaseAuth.unitypackage」,「FirebaseDatabase.unitypackage」をインポートする
・ダウンロードした「google_services.json」をAssets内のどこかに入れる（例：Assets/google_services.json）
・ダウンロードされたp12ファイルを「Editor Default Resources」に入れる
#プログラム

SetEditorDatabaseUrl
SetEditorP12FileName
SetEditorServiceAccountEmail
SetEditorP12Password
はコンソールで作成したものを設定する
DatabaseUrlはコンソールの「Database」で確認できる

エディタで試すと毎回ユーザーが作られる（そういうものなのか、どこか設定が足りないのか…）
仕方がないので拡張でGetUserId()という関数を追加し、ID固定になるようにしています
Android実機だと問題ないです

~~~csharp
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Firebase;
using Firebase.Unity.Editor;
using Firebase.Auth;
using Firebase.Database;
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 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;

		Signin();
		yield return null;
	}

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

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

	private void Signin()
	{
		var  user = _auth.CurrentUser;
		if( user == null )
		{
			_auth.SignInAnonymouslyAsync().ContinueWith( task =>
			{
				Debug.Log( "OnAuth" );
				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;
					OnCreateUser( newUser );
				}
			});
		}
		else
			OnSignin();
	}

	private void OnCreateUser( FirebaseUser newUser )
	{
		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( "OnCreateUser" );
			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" );

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

	private void 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() );

					if( _scrollRectUserData != null )
					{
						var content = _scrollRectUserData.content;
						var 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;
						}
					}
				}
			}
		});
	}
}

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

//ユーザーデータ
public class UserData
{
	public string userId;
	public int score;
}

~~~