Last active
June 2, 2021 09:17
-
-
Save bu-tokumitsu/751b7b6054552b7271462872f36e9082 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System; | |
using System.Security.Cryptography; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using System.Text; | |
// Firebase | |
using Firebase; | |
using Firebase.Extensions; | |
using Firebase.Auth; | |
using Firebase.Firestore; | |
// Sign In with Appleで使用(iOS) | |
using AppleAuth; | |
using AppleAuth.Enums; | |
using AppleAuth.Interfaces; | |
using AppleAuth.Extensions; | |
using AppleAuth.Native; | |
#if UNITY_IPHONE | |
// GameCenter認証で使用(iOS) | |
using UnityEngine.SocialPlatforms.GameCenter; | |
#endif | |
// Google認証 | |
using Google; | |
// Playgames認証で使用(Android) | |
using GooglePlayGames; | |
using GooglePlayGames.BasicApi; | |
using UnityEngine.SocialPlatforms; | |
public class FirebaseAuthDebugUI : MonoBehaviour { | |
// Firebaseの認証を行う | |
private Firebase.Auth.FirebaseAuth auth; | |
// 認証後のユーザー情報 | |
private Dictionary<string, Firebase.Auth.FirebaseUser> userByAuth = new Dictionary<string, Firebase.Auth.FirebaseUser>(); | |
// Android向け 最新のGooglePlay開発者サービスアプリがインストールされているかチェックに使用する | |
private Firebase.DependencyStatus dependencyStatus = Firebase.DependencyStatus.UnavailableOther; | |
// Sign In with Appleで使用する変数 | |
private const string AppleUserIdKey = "AppleUserId"; | |
private IAppleAuthManager appleAuthManager; | |
// Google認証で使用するクライアントID(プロジェクト毎に取得する) | |
private const string GoogleClientId = "{Web Client IDを設定}"; | |
// トークン取得判定のフラグ | |
private bool fetchingToken = false; | |
// UI表示に使用する | |
public GUISkin fb_GUISkin; | |
private string logText = ""; | |
private string displayName = ""; | |
private string sendMessage = ""; | |
private Vector2 controlsScrollViewVector = Vector2.zero; | |
private Vector2 scrollViewVector = Vector2.zero; | |
bool UIEnabled = true; | |
// ログ表示の最大サイズ | |
const int kMaxLogSize = 16382; | |
// ゲスト認証完了フラグ | |
private bool signedInGuest = false; | |
// ゲスト以外の認証完了フラグ | |
private bool signedInUser = false; | |
// Overridable function to allow additional controls to be added. | |
protected virtual void GUIDisplayCustomControls() { } | |
protected Task previousTask; | |
protected CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); | |
public virtual void Start() { | |
// GooglePlay開発者サービスアプリがインストールされているかチェックしてInitializeFirebase()を呼ぶ | |
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => { | |
dependencyStatus = task.Result; | |
if(dependencyStatus == Firebase.DependencyStatus.Available) | |
{ | |
InitializeFirebase(); | |
} | |
else | |
{ | |
Debug.LogError("Could not resolve all Firebase dependencies: " + dependencyStatus); | |
} | |
}); | |
StartWithSIWA(); | |
StartWithSignInGoogle(); | |
StartWithPlayGames(); | |
} | |
protected virtual void Update() { | |
if (Input.GetKeyDown(KeyCode.Escape)) | |
{ | |
Application.Quit(); | |
} | |
UpdateWithSIWA(); | |
} | |
void OnDestroy() { | |
// Firebase認証の状態監視を削除 | |
if (auth != null) | |
{ | |
auth.StateChanged -= AuthStateChanged; | |
auth.IdTokenChanged -= IdTokenChanged; | |
auth = null; | |
} | |
} | |
void DisableUI() { | |
UIEnabled = false; | |
} | |
void EnableUI() { | |
UIEnabled = true; | |
} | |
// UI下部に表示するログ情報 | |
public void DebugLog(string s) { | |
Debug.Log(s); | |
logText += s + "\n"; | |
while (logText.Length > kMaxLogSize) { | |
int index = logText.IndexOf("\n"); | |
logText = logText.Substring(index + 1); | |
} | |
scrollViewVector.y = int.MaxValue; | |
} | |
// 認証ユーザー情報のログ表示 | |
protected void DisplayUserInfo(Firebase.Auth.IUserInfo userInfo, int indentLevel) { | |
string indent = new String(' ', indentLevel * 2); | |
var userProperties = new Dictionary<string, string> { | |
{ "Display Name", userInfo.DisplayName }, | |
{ "Email", userInfo.Email} , | |
{ "Photo URL", userInfo.PhotoUrl != null ? userInfo.PhotoUrl.ToString() : null }, | |
{ "Provider ID", userInfo.ProviderId }, | |
{ "User ID", userInfo.UserId } | |
}; | |
foreach (var property in userProperties) { | |
if (!String.IsNullOrEmpty(property.Value)) | |
{ | |
DebugLog(String.Format("{0}{1}: {2}", indent, property.Key, property.Value)); | |
} | |
} | |
} | |
// 認証情報のログ表示 | |
protected void DisplayDetailedUserInfo(Firebase.Auth.FirebaseUser user, int indentLevel) { | |
string indent = new String(' ', indentLevel * 2); | |
DisplayUserInfo(user, indentLevel); | |
DebugLog(String.Format("{0}Anonymous: {1}", indent, user.IsAnonymous)); | |
DebugLog(String.Format("{0}Email Verified: {1}", indent, user.IsEmailVerified)); | |
DebugLog(String.Format("{0}Phone Number: {1}", indent, user.PhoneNumber)); | |
var providerDataList = new List<Firebase.Auth.IUserInfo>(user.ProviderData); | |
var numberOfProviders = providerDataList.Count; | |
if (numberOfProviders > 0) | |
{ | |
for (int i = 0; i < numberOfProviders; ++i) { | |
DebugLog(String.Format("{0}Provider Data: {1}", indent, i)); | |
DisplayUserInfo(providerDataList[i], indentLevel + 2); | |
} | |
} | |
} | |
// 実行Taskのログ出し | |
protected bool LogTaskCompletion(Task task, string operation) { | |
bool complete = false; | |
if (task.IsCanceled) | |
{ | |
DebugLog(operation + " canceled."); | |
} | |
else if (task.IsFaulted) | |
{ | |
DebugLog(operation + " encounted an error."); | |
foreach (Exception exception in task.Exception.Flatten().InnerExceptions) { | |
string authErrorCode = ""; | |
Firebase.FirebaseException firebaseEx = exception as Firebase.FirebaseException; | |
if (firebaseEx != null) | |
{ | |
authErrorCode = String.Format("AuthError.{0}: ", ((Firebase.Auth.AuthError)firebaseEx.ErrorCode).ToString()); | |
} | |
DebugLog(authErrorCode + exception.ToString()); | |
} | |
} | |
else if (task.IsCompleted) | |
{ | |
DebugLog(operation + " completed"); | |
complete = true; | |
} | |
return complete; | |
} | |
// GUIのレンダリング | |
void OnGUI() { | |
GUI.skin = fb_GUISkin; | |
if (dependencyStatus != Firebase.DependencyStatus.Available) | |
{ | |
GUILayout.Label("One or more Firebase dependencies are not present."); | |
GUILayout.Label("Current dependency status: " + dependencyStatus.ToString()); | |
return; | |
} | |
Rect logArea, controlArea; | |
// 画面表示が縦・横の時の割合表示 | |
if (Screen.width < Screen.height) | |
{ | |
// Portrait mode | |
controlArea = new Rect(0.0f, 0.0f, Screen.width, Screen.height * 0.7f); | |
logArea = new Rect(0.0f, Screen.height * 0.7f, Screen.width, Screen.height * 0.3f); | |
} | |
else | |
{ | |
// Landscape mode | |
controlArea = new Rect(0.0f, 0.0f, Screen.width * 0.5f, Screen.height); | |
logArea = new Rect(Screen.width * 0.5f, 0.0f, Screen.width * 0.5f, Screen.height); | |
} | |
GUILayout.BeginArea(logArea); | |
GUIDisplayLog(); | |
GUILayout.EndArea(); | |
GUILayout.BeginArea(controlArea); | |
GUIDisplayControls(); | |
GUILayout.EndArea(); | |
} | |
private class ScopedGuiEnabledModifier : IDisposable { | |
private bool wasEnabled; | |
public ScopedGuiEnabledModifier(bool newValue) { | |
wasEnabled = GUI.enabled; | |
GUI.enabled = newValue; | |
} | |
public void Dispose() { | |
GUI.enabled = wasEnabled; | |
} | |
} | |
// 上部のUI表示(認証ボタンの表示など) | |
void GUIDisplayControls() { | |
if (UIEnabled) { | |
controlsScrollViewVector = GUILayout.BeginScrollView(controlsScrollViewVector); | |
GUILayout.BeginVertical(); | |
GUIStyle titleLabelStyle = new GUIStyle(); | |
titleLabelStyle.fontSize = 96; | |
titleLabelStyle.normal.textColor = Color.white; | |
GUIStyle btnLabelStyle = GUI.skin.GetStyle("Button"); | |
btnLabelStyle.fontSize = 54; | |
btnLabelStyle.normal.textColor = Color.white; | |
GUIStyle textFieldStyle = GUI.skin.GetStyle("TextField"); | |
textFieldStyle.fontSize = 54; | |
textFieldStyle.normal.textColor = Color.white; | |
GUILayout.Space(162); | |
GUILayout.BeginHorizontal(); | |
{ | |
GUILayout.FlexibleSpace(); | |
GUILayout.Label("Firebase Auth", titleLabelStyle); | |
GUILayout.FlexibleSpace(); | |
} | |
GUILayout.EndHorizontal(); | |
GUILayout.Space(96); | |
GUILayout.BeginHorizontal(); | |
{ | |
GUILayout.FlexibleSpace(); | |
using (new ScopedGuiEnabledModifier(!signedInGuest && !signedInUser)) | |
{ | |
if (GUILayout.Button("Guest", btnLabelStyle, GUILayout.Width(Screen.width * 0.7f), GUILayout.Height(126))) | |
{ | |
SigninAnonymouslyAsync(); | |
} | |
} | |
GUILayout.FlexibleSpace(); | |
} | |
GUILayout.EndHorizontal(); | |
GUILayout.Space(48); | |
#if UNITY_IPHONE | |
GUILayout.BeginHorizontal(); | |
{ | |
GUILayout.FlexibleSpace(); | |
using (new ScopedGuiEnabledModifier(!signedInUser)) | |
{ | |
if (GUILayout.Button("Sign In with Apple", btnLabelStyle, GUILayout.Width(Screen.width * 0.7f), GUILayout.Height(126))) | |
{ | |
SignInWithApple(); | |
} | |
} | |
GUILayout.FlexibleSpace(); | |
} | |
GUILayout.EndHorizontal(); | |
GUILayout.Space(48); | |
GUILayout.BeginHorizontal(); | |
{ | |
GUILayout.FlexibleSpace(); | |
using (new ScopedGuiEnabledModifier(!signedInUser)) | |
{ | |
if (GUILayout.Button("GameCenter", btnLabelStyle, GUILayout.Width(Screen.width * 0.7f), GUILayout.Height(126))) | |
{ | |
SignInGameCenter(); | |
} | |
} | |
GUILayout.FlexibleSpace(); | |
} | |
GUILayout.EndHorizontal(); | |
GUILayout.Space(48); | |
#elif UNITY_ANDROID | |
GUILayout.BeginHorizontal(); | |
{ | |
GUILayout.FlexibleSpace(); | |
using (new ScopedGuiEnabledModifier(!signedInUser)) | |
{ | |
if (GUILayout.Button("Sign in Google", btnLabelStyle, GUILayout.Width(Screen.width * 0.7f), GUILayout.Height(126))) | |
{ | |
SignInGoogle(); | |
} | |
} | |
GUILayout.FlexibleSpace(); | |
} | |
GUILayout.EndHorizontal(); | |
GUILayout.Space(48); | |
GUILayout.BeginHorizontal(); | |
{ | |
GUILayout.FlexibleSpace(); | |
using (new ScopedGuiEnabledModifier(!signedInUser)) | |
{ | |
if (GUILayout.Button("Play game", btnLabelStyle, GUILayout.Width(Screen.width * 0.7f), GUILayout.Height(126))) | |
{ | |
SignInPlayGames(); | |
} | |
} | |
GUILayout.FlexibleSpace(); | |
} | |
GUILayout.EndHorizontal(); | |
GUILayout.Space(48); | |
#endif | |
GUILayout.BeginHorizontal(); | |
{ | |
GUILayout.FlexibleSpace(); | |
// using (new ScopedGuiEnabledModifier(signedInUser)) | |
// { | |
if (GUILayout.Button("Read FireStore message", btnLabelStyle, GUILayout.Width(Screen.width * 0.7f), GUILayout.Height(126))) | |
{ | |
StartCoroutine(ReadDoc(GetCollectionReference())); | |
} | |
// } | |
GUILayout.FlexibleSpace(); | |
} | |
GUILayout.EndHorizontal(); | |
GUILayout.Space(48); | |
GUILayout.BeginHorizontal(); | |
{ | |
GUILayout.FlexibleSpace(); | |
sendMessage = GUILayout.TextField(sendMessage, textFieldStyle, GUILayout.Width(Screen.width * 0.9f), GUILayout.Height(126)); | |
GUILayout.FlexibleSpace(); | |
} | |
GUILayout.EndHorizontal(); | |
GUILayout.Space(32); | |
GUILayout.BeginHorizontal(); | |
{ | |
GUILayout.FlexibleSpace(); | |
// using (new ScopedGuiEnabledModifier(signedInUser)) | |
// { | |
if (GUILayout.Button("Send FireStore message", btnLabelStyle, GUILayout.Width(Screen.width * 0.7f), GUILayout.Height(126))) | |
{ | |
FirestoreSendTest(); | |
} | |
// } | |
GUILayout.FlexibleSpace(); | |
} | |
GUILayout.EndHorizontal(); | |
GUIDisplayCustomControls(); | |
GUILayout.EndVertical(); | |
GUILayout.EndScrollView(); | |
} | |
} | |
// 画面下部のUI表示(ログ表示) | |
void GUIDisplayLog() { | |
GUIStyle logLabelStyle = new GUIStyle(); | |
logLabelStyle.fontSize = 36; | |
logLabelStyle.normal.textColor = Color.white; | |
scrollViewVector = GUILayout.BeginScrollView(scrollViewVector); | |
GUILayout.Label(logText, logLabelStyle); | |
GUILayout.EndScrollView(); | |
} | |
/** Firebase Authの必要処理 **/ | |
// Firebase認証の初期化処理 | |
protected void InitializeFirebase() { | |
DebugLog("Setting up Firebase Auth"); | |
auth = Firebase.Auth.FirebaseAuth.DefaultInstance; | |
// Firebase認証の状態監視を追加 | |
auth.StateChanged += AuthStateChanged; | |
auth.IdTokenChanged += IdTokenChanged; | |
AuthStateChanged(this, null); | |
} | |
// 認証状態が変更された時に実行される | |
void AuthStateChanged(object sender, System.EventArgs eventArgs) { | |
Firebase.Auth.FirebaseAuth senderAuth = sender as Firebase.Auth.FirebaseAuth; | |
Firebase.Auth.FirebaseUser user = null; | |
if (senderAuth != null) userByAuth.TryGetValue(senderAuth.App.Name, out user); | |
if (senderAuth == auth && senderAuth.CurrentUser != user) | |
{ | |
bool signedIn = user != senderAuth.CurrentUser && senderAuth.CurrentUser != null; | |
if (!signedIn && user != null) | |
{ | |
DebugLog("Signed out " + user.UserId); | |
} | |
user = senderAuth.CurrentUser; | |
userByAuth[senderAuth.App.Name] = user; | |
if (signedIn) | |
{ | |
signedInGuest = user.IsAnonymous; | |
signedInUser = !user.IsAnonymous; | |
DebugLog("AuthStateChanged Signed in " + user.UserId); | |
displayName = user.DisplayName ?? ""; | |
DisplayDetailedUserInfo(user, 1); | |
} | |
} | |
} | |
// Track ID token changes. | |
void IdTokenChanged(object sender, System.EventArgs eventArgs) { | |
Firebase.Auth.FirebaseAuth senderAuth = sender as Firebase.Auth.FirebaseAuth; | |
if (senderAuth == auth && senderAuth.CurrentUser != null && !fetchingToken) | |
{ | |
senderAuth.CurrentUser.TokenAsync(false).ContinueWithOnMainThread( | |
task => DebugLog(String.Format("Token[0:8] = {0}", task.Result.Substring(0, 8)))); | |
} | |
} | |
// 匿名(ゲスト)ユーザー認証 | |
public Task SigninAnonymouslyAsync() { | |
DebugLog("Attempting to sign anonymously..."); | |
DisableUI(); | |
return auth.SignInAnonymouslyAsync().ContinueWithOnMainThread(HandleSignInWithUser); | |
} | |
// サインアウト | |
protected void SignOut() { | |
DebugLog("Signing out."); | |
auth.SignOut(); | |
} | |
/** Sign In with Appleに必要な実装 **/ | |
// Start()で呼び出す初期化処理 | |
private void StartWithSIWA() { | |
// Sign In with Apple認証がサポートされている端末なら認証用のインスタンスを初期化する | |
if (AppleAuthManager.IsCurrentPlatformSupported) | |
{ | |
var deserializer = new PayloadDeserializer(); | |
this.appleAuthManager = new AppleAuthManager(deserializer); | |
} | |
} | |
// Update()で呼び出す処理 | |
private void UpdateWithSIWA() { | |
// SignInwithAppleを成功させる為にAppleAuthManagerのUpdate()をUpdate()で呼び続ける必要がある | |
if (this.appleAuthManager != null) | |
{ | |
this.appleAuthManager.Update(); | |
} | |
} | |
private static string GenerateRandomString(int length) | |
{ | |
if (length <= 0) | |
{ | |
throw new Exception("Expected nonce to have positive length"); | |
} | |
const string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._"; | |
var cryptographicallySecureRandomNumberGenerator = new RNGCryptoServiceProvider(); | |
var result = string.Empty; | |
var remainingLength = length; | |
var randomNumberHolder = new byte[1]; | |
while (remainingLength > 0) | |
{ | |
var randomNumbers = new List<int>(16); | |
for (var randomNumberCount = 0; randomNumberCount < 16; randomNumberCount++) | |
{ | |
cryptographicallySecureRandomNumberGenerator.GetBytes(randomNumberHolder); | |
randomNumbers.Add(randomNumberHolder[0]); | |
} | |
for (var randomNumberIndex = 0; randomNumberIndex < randomNumbers.Count; randomNumberIndex++) | |
{ | |
if (remainingLength == 0) | |
{ | |
break; | |
} | |
var randomNumber = randomNumbers[randomNumberIndex]; | |
if (randomNumber < charset.Length) | |
{ | |
result += charset[randomNumber]; | |
remainingLength--; | |
} | |
} | |
} | |
return result; | |
} | |
private static string GenerateSHA256NonceFromRawNonce(string rawNonce) | |
{ | |
var sha = new SHA256Managed(); | |
var utf8RawNonce = Encoding.UTF8.GetBytes(rawNonce); | |
var hash = sha.ComputeHash(utf8RawNonce); | |
var result = string.Empty; | |
for (var i = 0; i < hash.Length; i++) | |
{ | |
result += hash[i].ToString("x2"); | |
} | |
return result; | |
} | |
// Sign In with Apple認証の実行 | |
private void SignInWithApple() { | |
var rawNonce = GenerateRandomString(32); | |
var nonce = GenerateSHA256NonceFromRawNonce(rawNonce); | |
var loginArgs = new AppleAuthLoginArgs(LoginOptions.IncludeEmail | LoginOptions.IncludeFullName, nonce); | |
// iOSクライアントでSIWA認証を実行し、成功時のcredentialとNonceを使用してFirebaseAuthを実行する | |
this.appleAuthManager.LoginWithAppleId(loginArgs, | |
credential => | |
{ | |
var appleIdCredential = credential as IAppleIDCredential; | |
DebugLog(String.Format("appleIdCredential:{0} | rawNonce:{1}", appleIdCredential, rawNonce)); | |
if (appleIdCredential != null) | |
{ | |
DebugLog(String.Format("appleIdCredential:{0} | rawNonce:{1}", appleIdCredential, rawNonce)); | |
var identityToken = Encoding.UTF8.GetString(appleIdCredential.IdentityToken); | |
var authorizationCode = Encoding.UTF8.GetString(appleIdCredential.AuthorizationCode); | |
Credential firebaseCredential = OAuthProvider.GetCredential("apple.com", identityToken, rawNonce, authorizationCode); | |
SignInOrLinkCredentialAsync(firebaseCredential); | |
} | |
}, | |
error => | |
{ | |
// Something went wrong | |
var authorizationErrorCode = error.GetAuthorizationErrorCode(); | |
DebugLog("SignInWithApple error:" + authorizationErrorCode); | |
} | |
); | |
} | |
// GameCenter認証 | |
private void SignInGameCenter() { | |
Social.localUser.Authenticate(success => { | |
if (success) | |
{ | |
var credentialTask = Firebase.Auth.GameCenterAuthProvider.GetCredentialAsync(); | |
var continueTask = credentialTask.ContinueWithOnMainThread(task => { | |
if(!task.IsCompleted) | |
return; | |
if(task.Exception != null) | |
DebugLog("GC Credential Task - Exception: " + task.Exception.Message); | |
Credential credential = task.Result; | |
SignInOrLinkCredentialAsync(credential); | |
}); | |
} | |
else | |
{ | |
DebugLog("GameCenter authenticate error"); | |
} | |
}); | |
} | |
/** Google認証に必要な実装 **/ | |
// Start()で呼び出す初期化処理 | |
private void StartWithSignInGoogle() { | |
// Google SignInの設定 | |
GoogleSignIn.Configuration = new GoogleSignInConfiguration { | |
RequestIdToken = true, | |
// Copy this value from the google-service.json file. | |
// oauth_client with type == 3 | |
WebClientId = GoogleClientId | |
}; | |
} | |
// Google認証 | |
private void SignInGoogle() { | |
Task<GoogleSignInUser> signIn = GoogleSignIn.DefaultInstance.SignIn(); | |
signIn.ContinueWith (task => { | |
if (task.IsCanceled) { | |
DebugLog("GoogleSignIn was canceled."); | |
} else if (task.IsFaulted) { | |
DebugLog("GoogleSignIn was error."); | |
} else { | |
Credential credential = Firebase.Auth.GoogleAuthProvider.GetCredential(((Task<GoogleSignInUser>)task).Result.IdToken, null); | |
SignInOrLinkCredentialAsync(credential); | |
} | |
}); | |
} | |
/** Playgamesに必要な実装 **/ | |
// Start()で呼び出す初期化処理 | |
private void StartWithPlayGames() { | |
#if UNITY_ANDROID | |
// playgames設定、初期化 | |
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder() | |
.RequestServerAuthCode(false /* Don't force refresh */) | |
.Build(); | |
PlayGamesPlatform.InitializeInstance(config); | |
PlayGamesPlatform.Activate(); | |
#endif | |
} | |
// Playゲーム認証(iOSだとエラーになるのでAndroidでのみ呼び出す) | |
#if UNITY_ANDROID | |
private void SignInPlayGames() { | |
Social.localUser.Authenticate(success => { | |
if (success) | |
{ | |
var authCode = PlayGamesPlatform.Instance.GetServerAuthCode(); | |
Firebase.Auth.FirebaseAuth auth = Firebase.Auth.FirebaseAuth.DefaultInstance; | |
Credential credential = Firebase.Auth.PlayGamesAuthProvider.GetCredential(authCode); | |
SignInOrLinkCredentialAsync(credential); | |
} | |
else | |
{ | |
DebugLog("Playgames authenticate error"); | |
} | |
}); | |
} | |
#endif | |
// ゲストユーザーで認証済みの時はリンクさせる、新規の場合はそのまま認証完了 | |
private void SignInOrLinkCredentialAsync(Credential firebaseCredential) { | |
if(auth.CurrentUser != null && auth.CurrentUser.IsAnonymous) | |
{ | |
auth.CurrentUser.LinkWithCredentialAsync(firebaseCredential).ContinueWith(task => { | |
if (task.IsCanceled) | |
{ | |
DebugLog("LinkWithCredentialAsync was canceled."); | |
return; | |
} | |
if (task.IsFaulted) | |
{ | |
DebugLog("LinkWithCredentialAsync encountered an error: " + task.Exception.Message); | |
return; | |
} | |
Firebase.Auth.FirebaseUser newUser = task.Result; | |
DebugLog(String.Format("Credentials successfully linked to Firebase user: {0} ({1})", newUser.DisplayName, newUser.UserId)); | |
signedInGuest = newUser.IsAnonymous; | |
signedInUser = !newUser.IsAnonymous; | |
}); | |
} | |
else | |
{ | |
var task = auth.SignInWithCredentialAsync(firebaseCredential); | |
if(task.Exception != null) | |
DebugLog("GC Credential Task - Exception: " + task.Exception.Message); | |
task.ContinueWithOnMainThread(HandleSignInWithUser); | |
} | |
} | |
// 認証結果の取得 | |
void HandleSignInWithUser(Task<Firebase.Auth.FirebaseUser> task) { | |
EnableUI(); | |
if(task.IsCanceled) | |
{ | |
DebugLog("Firebase auth was canceled"); | |
} | |
else if(task.IsFaulted) | |
{ | |
DebugLog("Firebase auth failed"); | |
} | |
else if(LogTaskCompletion(task, "Sign-in")) | |
{ | |
// FirebaseUserの取得 | |
// Firebase.Auth.FirebaseUser newUser = task.Result; | |
DebugLog(String.Format("{0} signed in", task.Result.DisplayName)); | |
} | |
} | |
// ここからFirestore | |
private string collectionPath = "send_test"; | |
private string documentId = ""; | |
protected FirebaseFirestore db { | |
get { | |
return FirebaseFirestore.DefaultInstance; | |
} | |
} | |
private CollectionReference GetCollectionReference() { | |
return db.Collection(collectionPath); | |
} | |
private DocumentReference GetDocumentReference() { | |
if (documentId == "") { | |
return GetCollectionReference().Document(); | |
} | |
return GetCollectionReference().Document(documentId); | |
} | |
// 読み込み | |
private IEnumerator ReadDoc(Query query) { | |
Task<QuerySnapshot> getTask = query.GetSnapshotAsync(); | |
yield return new WaitForTaskCompletion(this, getTask); | |
if (!(getTask.IsFaulted || getTask.IsCanceled)) | |
{ | |
QuerySnapshot allCitiesQuerySnapshot = getTask.Result; | |
foreach (DocumentSnapshot documentSnapshot in allCitiesQuerySnapshot.Documents) | |
{ | |
Console.WriteLine("read document data for {0} document:", documentSnapshot.Id); | |
Dictionary<string, object> city = documentSnapshot.ToDictionary(); | |
IDictionary<string, object> resultData = documentSnapshot.ToDictionary(); | |
foreach (KeyValuePair<string, object> kv in resultData) | |
{ | |
DebugLog(String.Format("read key = {0} : value = {1}", kv.Key, kv.Value)); | |
} | |
} | |
} | |
} | |
// 書き込み | |
private IEnumerator WriteDoc(DocumentReference doc, IDictionary<string, object> data) { | |
Task setTask = doc.SetAsync(data); | |
yield return new WaitForTaskCompletion(this, setTask); | |
if (!(setTask.IsFaulted || setTask.IsCanceled)) | |
{ | |
foreach (KeyValuePair<string, object> kv in data) | |
{ | |
DebugLog(String.Format("write key = {0} : value = {1}", kv.Key, kv.Value)); | |
} | |
} | |
} | |
// テスト送信 | |
private void FirestoreSendTest() { | |
var msg = "test"; | |
if (sendMessage != "") | |
{ | |
msg = sendMessage; | |
} | |
var data = new Dictionary<string, object>{ | |
{"message", msg} | |
}; | |
StartCoroutine(WriteDoc(GetDocumentReference(), data)); | |
} | |
class WaitForTaskCompletion : CustomYieldInstruction { | |
Task task; | |
FirebaseAuthDebugUI debugUI; | |
public WaitForTaskCompletion(FirebaseAuthDebugUI debugUI, Task task) { | |
debugUI.previousTask = task; | |
this.debugUI = debugUI; | |
this.task = task; | |
} | |
public override bool keepWaiting { | |
get { | |
if (task.IsCompleted) | |
{ | |
debugUI.cancellationTokenSource = new CancellationTokenSource(); | |
if (task.IsFaulted) | |
{ | |
Debug.Log("WaitForTaskCompletion exception:" + task.Exception.Message); | |
} | |
return false; | |
} | |
return true; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment