Firebaseの匿名認証(Android)
※この記事は2017年05月29日にqiitaに投稿した内容です。
環境
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実機だと問題ないです
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;
}