Skip to content

Instantly share code, notes, and snippets.

@bhupiister
Created March 22, 2021 04:25
Show Gist options
  • Save bhupiister/673c259613c8cc060dcc54a88042cdaf to your computer and use it in GitHub Desktop.
Save bhupiister/673c259613c8cc060dcc54a88042cdaf to your computer and use it in GitHub Desktop.
#if UNITY_ANDROID || UNITY_IOS || UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Firebase;
using Firebase.Auth;
using Google;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using System.Text.RegularExpressions;
using System.Collections;
public class Authentication : MonoBehaviour
{
public string webClientId = "<your client id here>";
[SerializeField] private string sceneToJump;
[SerializeField] private string sceneToLoad;
public InputField emailInp;
public InputField passwordInp;
public InputField confirmPasswordInp;
public Text warningInfo;
FirebaseAuth auth;
FirebaseUser user;
PhoneAuthProvider provider;
private string phoneId;
private GoogleSignInConfiguration configuration;
public GameObject VerificationPanel;
public Text EmailConfirmationMessage;
public Button SendEmailButton;
public Button ResendEmailButton;
public GameObject emailVerifyDoneCheck;
public GameObject phoneVerifyDoneCheck;
public Text warningEmailVerify;
public InputField countryCodeInp;
public InputField phoneNumberInp;
public InputField OTPInp;
public Button sendOTPButton;
public Button submitOTPButton;
public Text warningPhoneVerify;
public Button VerificationDoneButton;
public const string MatchEmailPattern =
@"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@"
+ @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\."
+ @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
+ @"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})$";
private void Awake()
{
Debug.Log("Authentication_Stage1");
configuration = new GoogleSignInConfiguration { WebClientId = webClientId, RequestEmail = true, RequestIdToken = true };
Debug.Log("Authentication_Stage2: " + webClientId);
Initialize();
}
private void Initialize()
{
Debug.Log("Authentication_Stage3");
auth = FirebaseAuth.DefaultInstance;
auth.StateChanged += AuthStateChanged;
AuthStateChanged(this, null);
}
public void SignInWithGoogle() { OnSignIn(); }
public void SignOutFromGoogle() { OnSignOut(); }
public void SignInWithEmailAndPassword()
{
var email = emailInp.text;
var password = passwordInp.text;
bool emailRegExp = IsEmail(email);
if (emailRegExp)
{
if (password.Length > 6)
{
SignInWithEmailAndPassword(email, password);
warningInfo.text = "Everthing is perfect to SingIn";
}
else
{
warningInfo.text = "Password should have atleast 6 characters!";
}
}
else
{
warningInfo.text = "Please enter valid Email address!";
}
}
public void SignUpWithEmailAndPassword()
{
var email = emailInp.text;
var password = passwordInp.text;
var confirmPassword = confirmPasswordInp.text;
bool emailRegExp = IsEmail(email);
if (emailRegExp)
{
if (password.Length > 6)
{
if (password == confirmPassword)
{
SignUpWithEmailAndPassword(email, password);
warningInfo.text = "Everthing is perfect to SignUp";
}
else
{
warningInfo.text = "Password and confirm password does not match!";
}
}
else
{
warningInfo.text = "Password should have atleast 6 characters!";
}
}
else
{
warningInfo.text = "Please enter valid Email address!";
}
}
public static bool IsEmail(string email)
{
if (email != null) return Regex.IsMatch(email, MatchEmailPattern);
else return false;
}
public void HidePasswordText()
{
passwordInp.contentType = InputField.ContentType.Password;
confirmPasswordInp.contentType = InputField.ContentType.Password;
passwordInp.ForceLabelUpdate();
confirmPasswordInp.ForceLabelUpdate();
}
public void ShowPasswordText()
{
passwordInp.contentType = InputField.ContentType.Standard;
confirmPasswordInp.contentType = InputField.ContentType.Standard;
passwordInp.ForceLabelUpdate();
confirmPasswordInp.ForceLabelUpdate();
}
private void OnSignIn()
{
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = false;
GoogleSignIn.Configuration.RequestIdToken = true;
Debug.Log("Calling SignIn");
Debug.Log("Authentication_Stage4");
Debug.Log("Authentication_Stage4.1");
GoogleSignIn.DefaultInstance.SignIn().ContinueWith(OnAuthenticationFinished);
Debug.Log("Authentication_Stage4.2");
}
private void OnSignOut()
{
Debug.Log("Calling SignOut");
GoogleSignIn.DefaultInstance.SignOut();
FirebaseAuth.DefaultInstance.SignOut();
}
public void OnDisconnect()
{
Debug.Log("Calling Disconnect");
GoogleSignIn.DefaultInstance.Disconnect();
}
internal void OnAuthenticationFinished(Task<GoogleSignInUser> task)
{
Debug.Log("Authentication_Stage5");
if (task.IsFaulted)
{
using (IEnumerator<Exception> enumerator = task.Exception.InnerExceptions.GetEnumerator())
{
if (enumerator.MoveNext())
{
Debug.Log("Authentication_Stage5.1");
GoogleSignIn.SignInException error = (GoogleSignIn.SignInException)enumerator.Current;
Debug.Log("Got Error: " + error.Status + " " + error.Message);
Debug.Log("Authentication_Stage5.2");
}
else
{
Debug.Log("Got Unexpected Exception?!?" + task.Exception);
Debug.Log("Authentication_Stage6");
}
}
}
else if (task.IsCanceled)
{
Debug.Log("Canceled");
}
else
{
Debug.Log("Welcome: " + task.Result.DisplayName + "!");
Debug.Log("Email = " + task.Result.Email);
//AddToInformation("Google ID Token = " + task.Result.IdToken);
Debug.Log("Authentication_Stage7");
SignInWithGoogleOnFirebase(task.Result.IdToken);
}
}
private void SignInWithEmailAndPassword(string email, string password)
{
auth.StateChanged += AuthStateChanged;
auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("SignInWithEmailAndPasswordAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SignInWithEmailAndPasswordAsync encountered an error: " + task.Exception);
return;
}
user = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1}) ({2})",
user.DisplayName, user.UserId, user.IsEmailVerified);
//CheckUser();
});
}
private void SignUpWithEmailAndPassword(string email, string password)
{
auth.StateChanged += AuthStateChanged;
auth.CreateUserWithEmailAndPasswordAsync(email, password).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("CreateUserWithEmailAndPasswordAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("CreateUserWithEmailAndPasswordAsync encountered an error: " + task.Exception);
return;
}
// Firebase user has been created.
user = task.Result;
Debug.LogFormat("Firebase user created successfully: {0} ({1})",
user.DisplayName, user.UserId);
//CheckUser();
});
}
private void SignInWithGoogleOnFirebase(string idToken)
{
Credential credential = GoogleAuthProvider.GetCredential(idToken, null);
auth.StateChanged += AuthStateChanged;
Debug.Log("Authentication_Stage8");
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
AggregateException ex = task.Exception;
if (ex != null)
{
if (ex.InnerExceptions[0] is FirebaseException inner && (inner.ErrorCode != 0))
{
Debug.Log("Authentication_Stage9");
Debug.Log("\nError code = " + inner.ErrorCode + " Message = " + inner.Message);
}
}
else
{
Debug.Log("Sign in Successful.");
FirebaseUser newUser = task.Result;
Debug.Log("Authentication_Stage10");
Debug.LogFormat("User signed in successfully: {0} ({1}) Email verified?:{2}", newUser.DisplayName, newUser.UserId, newUser.IsEmailVerified);
}
});
}
public void SkipToLoggedIn()
{
SceneManager.LoadScene(sceneToJump);
}
private void AuthStateChanged(object sender, EventArgs eventArgs)
{
if (auth.CurrentUser != user)
{
bool signedIn = user != auth.CurrentUser && auth.CurrentUser != null;
if (!signedIn && user != null)
{
Debug.Log("Signed out " + user.UserId);
}
user = auth.CurrentUser;
if (signedIn)
{
Debug.Log("Checking Authetication in AuthStateChanged");
Debug.Log("Signed in " + user.UserId);
CheckUser();
}
}
}
public void CheckUser()
{
Debug.Log("Authentication_Stage11");
if (FirebaseAuth.DefaultInstance.CurrentUser != null)
{
user.ReloadAsync();
//user = auth.CurrentUser;
Debug.Log("User Info: " + user.Email + " - " + user.PhoneNumber + " - " + user.IsEmailVerified);
VerifyEmailAndPhone();
Debug.Log("Authentication_Stage12");
Debug.Log("Proceeding to loggedIn Screen");
}
else
{
Debug.Log("Authentication_Stage13");
}
}
public void VerifyEmailAndPhone()
{
if (user.PhoneNumber != "" && user.IsEmailVerified == true)
{
Debug.LogFormat("Phone number:{0} and emailBool:{1}", user.PhoneNumber, user.IsEmailVerified);
VerificationPanel.SetActive(false);
SceneManager.LoadScene(sceneToLoad);
}
else
{
Debug.Log("Code to get inside GetverificationPanle");
StartCoroutine(WaitAndDoSomething());
}
}
private int V = 0;
public void GetVerificationPanel()
{
Debug.Log("Inside GetverificationPanle");
VerificationPanel.SetActive(true);
warningEmailVerify.text = "";
warningPhoneVerify.text = "";
bool emailVerStatus = user.IsEmailVerified;
Debug.Log("emailVerStatus: " + emailVerStatus);
if (emailVerStatus == true)
{
EmailConfirmationMessage.text = "Thank you for verifying your email address.";
emailVerifyDoneCheck.SetActive(true);
SendEmailButton.gameObject.SetActive(false);
}
else
{
EmailConfirmationMessage.text = "We need to verify your email address " + user.Email + ". " + "Please click on Send email to receive verification email.";
emailVerifyDoneCheck.SetActive(false);
SendEmailButton.gameObject.SetActive(true);
if (V > 0)
{
warningEmailVerify.text = "Please verify your email address.";
}
}
if (user.PhoneNumber != "")
{
phoneVerifyDoneCheck.SetActive(true);
countryCodeInp.interactable = false;
phoneNumberInp.interactable = false;
OTPInp.interactable = false;
submitOTPButton.interactable = false;
sendOTPButton.interactable = false;
}
else
{
phoneVerifyDoneCheck.SetActive(false);
countryCodeInp.interactable = true;
phoneNumberInp.interactable = true;
OTPInp.interactable = true;
submitOTPButton.interactable = true;
sendOTPButton.interactable = true;
if (V > 0)
{
warningPhoneVerify.text = "Please verify your Phone number.";
}
V++;
}
}
IEnumerator WaitAndDoSomething()
{
yield return new WaitForSeconds(3f);
// do something
GetVerificationPanel();
}
public void SendVerificationEmail()
{
SendEmailButton.gameObject.SetActive(false);
if (user != null)
{
user.SendEmailVerificationAsync().ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("SendEmailVerificationAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SendEmailVerificationAsync encountered an error: " + task.Exception);
return;
}
Debug.Log("Email sent successfully.");
});
}
}
uint phoneAuthTimeoutMs = 10000;
public void SendOTPMsg()
{
var phoneNumber = "+" + countryCodeInp.text + phoneNumberInp.text;
provider = PhoneAuthProvider.GetInstance(auth);
provider.VerifyPhoneNumber(phoneNumber, phoneAuthTimeoutMs, null,
verificationCompleted: (credential) =>
{
// Auto-sms-retrieval or instant validation has succeeded (Android only).
// There is no need to input the verification code.
// `credential` can be used instead of calling GetCredential().
auth.CurrentUser.LinkWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("LinkWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("LinkWithCredentialAsync encountered an error: " + task.Exception);
return;
}
user = task.Result;
Debug.LogFormat("Credentials successfully linked to Firebase user: {0} ({1})",
user.DisplayName, user.UserId);
});
},
verificationFailed: (error) =>
{
// The verification code was not sent.
// `error` contains a human readable explanation of the problem.
},
codeSent: (id, token) =>
{
phoneId = id;
Debug.Log("Id: " + id);
PlayerPrefs.SetString("phoneId", id);
// Verification code was successfully sent via SMS.
// `id` contains the verification id that will need to passed in with
// the code from the user when calling GetCredential().
// `token` can be used if the user requests the code be sent again, to
// tie the two requests together.
},
codeAutoRetrievalTimeOut: (id) =>
{
// Called when the auto-sms-retrieval has timed out, based on the given
// timeout parameter.
// `id` contains the verification id of the request that timed out.
});
}
public void SubmitOtp()
{
var verificationCode = OTPInp.text;
Credential credential = provider.GetCredential(phoneId, verificationCode);
auth.CurrentUser.LinkWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("LinkWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("LinkWithCredentialAsync encountered an error: " + task.Exception);
return;
}
user = task.Result;
Debug.LogFormat("Credentials successfully linked to Firebase user: {0} ({1})",
user.DisplayName, user.UserId);
});
}
void OnDestroy()
{
FirebaseAuth.DefaultInstance.StateChanged -= AuthStateChanged;
if (auth != null)
{
auth.StateChanged -= AuthStateChanged;
auth = null;
}
}
public void ReloadScene()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment