I am currently implementing a Game Center authentication for my Unity game. When users sign in, I cannot see their username(identifier) in the Authentication section of Firebase Console. However, when authentication method is Play Games, identifiers of users can be seen in Firebase console . Here is my code:
private void AuthenticateToGameCenter() {
Social.localUser.Authenticate(success => {
if (success)
{
SignInWithGameCenterAsync();
}
else
{
SignInAnonymously();
}
});
}
private void SignInWithGameCenterAsync() {
auth = FirebaseAuth.DefaultInstance;
GameCenterAuthProvider.GetCredentialAsync().ContinueWithOnMainThread(task => {
if(!task.IsCompleted)
return;
if(task.Exception != null)
Debug.Log("GC Credential Task - Exception: " + task.Exception.Message);
var credential = task.Result;
auth.SignInWithCredentialAsync(credential).ContinueWithOnMainThread(task1 =>
{
if (task1.IsCanceled)
return;
if (task1.IsFaulted)
return;
}
);
}
}
I can get their username by Social.localUser.userName however I cannot see their username in Firebase.
Related
Does anyone know if it is possible and how to use firebase auth to give additional information, like the name of the User?
I created this method but it only stores emails and passwords.
public void create()
{
FirebaseAuth.DefaultInstance.CreateUserWithEmailAndPasswordAsync(emailInput.text, passwordInput.text).ContinueWith((task => {
if (task.IsCanceled)
{
Firebase.FirebaseException e = task.Exception.Flatten().InnerExceptions[0] as Firebase.FirebaseException;
GetErrorMessage((AuthError)e.ErrorCode);
return;
}
if (task.IsFaulted)
{
Firebase.FirebaseException e = task.Exception.Flatten().InnerExceptions[0] as Firebase.FirebaseException;
GetErrorMessage((AuthError)e.ErrorCode);
return;
}
if (task.IsCompleted)
{
print("Created user");
return;
}
}));
}
I'm new in unity and I started using firebase for about one week.
Sorry, if I asked something obvious, but I searched for days and the documentation is scarce.
Thanks
Use the FirebaseUser.UpdateUserProfileAsync
public void SetPlayerNameAndImage(string playerName, string imageUrl)
{
Firebase.Auth.FirebaseUser user = Firebase.Auth.FirebaseAuth.DefaultInstance.CurrentUser;
if (user != null)
{
Firebase.Auth.UserProfile profile = new Firebase.Auth.UserProfile
{
DisplayName = playerName,
PhotoUrl = new System.Uri(imageUrl),
};
user.UpdateUserProfileAsync(profile).ContinueWith(task => {
if (task.IsCanceled)
{
Debug.LogError("UpdateUserProfileAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("UpdateUserProfileAsync encountered an error: " + task.Exception);
return;
}
Debug.Log("User profile updated successfully.");
});
}
}
Firebase Authentication only has the ability to store per user in the dedicated fields for the user profile and custom claims. The blob of data for custom claims is limited to 1000 bytes of JSON, and it can only be written with a backend SDK, not the Unity client SDK. While you certainly can store data about the user in custom claims, that's not what it's intended to be used for (it's meant for granted access using backend security mechanisms).
What you should do instead is use a database, such as Realtime Database or Firestore to store per-user information, keyed by the Firbase Auth UID, and protect that with security rules so that each user can only access the data that you would like them to access.
So I've tried to use Firebase for unity and create a Facebook login for my project.
I've followed every instructions in firebase documentation and Facebook developer including importing SDK's into my projects and adding appID keyhashes in the Facebook login alone works fine but once I tried to send it into Firebase to keep login informations I kept getting exceptions.
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Facebook.Unity;
public class facebookLogin : MonoBehaviour {
// Use this for initialization
void Awake()
{
if (!FB.IsInitialized)
{
// Initialize the Facebook SDK
FB.Init(InitCallback, OnHideUnity);
}
else
{
// Already initialized, signal an app activation App Event
FB.ActivateApp();
}
}
private void InitCallback()
{
if (FB.IsInitialized)
{
// Signal an app activation App Event
FB.ActivateApp();
// Continue with Facebook SDK
// ...
}
else
{
Debug.Log("Failed to Initialize the Facebook SDK");
}
}
private void OnHideUnity(bool isGameShown)
{
if (!isGameShown)
{
// Pause the game - we will need to hide
Time.timeScale = 0;
}
else
{
// Resume the game - we're getting focus again
Time.timeScale = 1;
}
}
public void FBlogin()
{
List<string> permissions = new List<string>();
permissions.Add("public_profile");
permissions.Add("email");
permissions.Add("user_friends");
FB.LogInWithReadPermissions(permissions, AuthCallback);
}
private void AuthCallback(ILoginResult result)
{
if (FB.IsLoggedIn)
{
Firebase.Auth.FirebaseAuth auth =
Firebase.Auth.FirebaseAuth.DefaultInstance;
List<string> permissions = new List<string>();
// AccessToken class will have session details
var aToken = Facebook.Unity.AccessToken.CurrentAccessToken;
// Print current access token's User ID
Debug.Log(aToken.TokenString);
Debug.Log(aToken.UserId);
Firebase.Auth.Credential credential =
Firebase.Auth.FacebookAuthProvider.GetCredential(aToken.TokenString);
auth.SignInWithCredentialAsync(credential).ContinueWith(task
=> {
if (task.IsCanceled)
{
Debug.LogError("SignInWithCredentialAsync was
canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SignInWithCredentialAsync encountered
an error: " + task.Exception);
return;
}
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
// Print current access token's granted permissions
//foreach(string perms in aToken.Permissions)
//{
// Debug.Log(perms);
//}
}
else
{
Debug.Log("User cancelled login");
}
}
}
And here my exceptions:
SignInWithCredentialAsync encountered an error: System.AggregateException: Exception of type 'System.AggregateException' was thrown.
-----------------
Firebase.FirebaseException: An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address.
UnityEngine.Debug:LogError(Object)
facebookLogin:<AuthCallback>m__0(Task`1) (at Assets/Script/facebookLogin.cs:82)
System.Threading.Tasks.TaskCompletionSource`1:SetException(AggregateException)
Firebase.Internal.TaskCompletionSourceCompat`1:SetExceptionInternal(TaskCompletionSource`1, AggregateException)
Firebase.Internal.TaskCompletionSourceCompat`1:SetException(TaskCompletionSource`1, AggregateException)
Firebase.Auth.FirebaseAuth:CompleteFirebaseUserTask(Task`1, TaskCompletionSource`1)
Firebase.Auth.<SignInWithCredentialAsync>c__AnonStorey4:<>m__0(Task`1)
System.Threading.Tasks.TaskCompletionSource`1:SetException(Exception)
Firebase.Auth.<GetTask>c__AnonStorey0:<>m__0()
Firebase.Auth.Future_User:SWIG_CompletionDispatcher(Int32)
Firebase.AppUtilPINVOKE:PollCallbacks()
Firebase.AppUtil:PollCallbacks()
Firebase.Platform.FirebaseAppUtils:PollCallbacks()
Firebase.Platform.FirebaseHandler:Update()
Firebase.Platform.FirebaseMonoBehaviour:Update()
I have no idea what went wrong. It seems like something is wrong with SignInWithCredentialAsync but I have no idea how to fix it.
I don't see anything wrong with your code. As the error says, looks like there's another account already registered with the email of the Facebook account you're trying to login with. Does your app allow other login methods?
From Firebase Help:
You can configure whether users can create multiple accounts that use
the same email address, but are linked to different sign-in methods.
For example, if you don't allow multiple accounts with the same email
address, a user cannot create a new account that signs in using a
Google Account with the email address ex#gmail.com if there already is
an account that signs in using the email address ex#gmail.com and a
password.
Link: https://support.google.com/firebase/answer/6400716?hl=en
You can fix this in your Firebase console. In Authentication > Sign-in Method, scroll down and you will see the section "Multiple accounts per email address". Allow it and the error should be fixed.
I'm trying to get phone number authentication for Unity up and running but I am getting no SMS response. The documentation online is super unclear about how to do this. I'd much rather have Google Auth for Firebase but apparently it isn't supported yet. Can anyone help me figure out how to get this up and running?
Here is what I have so far...
public class SignIn : MonoBehaviour {
private string phoneNumber;
private string secureCode;
private uint phoneAuthTimeoutMs;
private Firebase.Auth.FirebaseAuth firebaseAuth;
private Credential credential;
private string verificationId;
private string verificationCode;
public Text PhoneNumberInputFieldText;
public Text SecureCodeInputFieldText;
public Button SendSecureCodeButton;
public Button SubmitSecureCodeButton;
// Use this for initialization
void Start()
{
SendSecureCodeButton.GetComponent<Button>().onClick.AddListener(() => StartSignIn());
}
// Update is called once per frame
void Update () {
}
void StartSignIn()
{
firebaseAuth = Firebase.Auth.FirebaseAuth.DefaultInstance;
phoneAuthTimeoutMs = 60000;
phoneNumber = PhoneNumberInputFieldText.text;
Debug.Log(phoneNumber);
if (PlayerPrefs.GetString("secureCode") != null)
{
verificationId = PlayerPrefs.GetString("secureCode");
}
PhoneAuthProvider provider = PhoneAuthProvider.GetInstance(firebaseAuth);
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().
},
verificationFailed: (error) =>
{
// The verification code was not sent.
// `error` contains a human readable explanation of the problem.
},
codeSent: (id, token) =>
{
//Prompt here to type in SecureCode
PlayerPrefs.SetString("secureCode", id);
credential = provider.GetCredential(verificationId, verificationCode);
firebaseAuth.SignInWithCredentialAsync(credential).ContinueWith(task => {
if (task.IsFaulted)
{
Debug.LogError("SignInWithCredentialAsync encountered an error: " +
task.Exception);
return;
}
FirebaseUser newUser = task.Result;
Debug.Log("User signed in successfully");
// This should display the phone number.
Debug.Log("Phone number: " + newUser.PhoneNumber);
// The phone number providerID is 'phone'.
Debug.Log("Phone provider ID: " + newUser.ProviderId);
});
// 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.
});
}
}
Thanks in advance!
Here is my Firebase Console:
I'll post an answer but i'll edit this.
Try a simplier sending SMS phone verification
Firebase.Auth.FirebaseAuth auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
phoneNumber = "your phone number here";//state the phone number here first
uint phoneAuthTimeoutMs = 10000;
PhoneAuthProvider provider = PhoneAuthProvider.GetInstance(auth);
provider.VerifyPhoneNumber(phoneNumber, phoneAuthTimeoutMs,null,
verificationCompleted: (credential) => {
},
verificationFailed: (error) => {
},
codeSent: (id, token) => {
MyText.text = "SMS Has been sent " + id;
},
codeAutoRetrievalTimeOut : (id) => {
});
MyText.text += "HMM";
Then please tell me if it works. Now if it works we will proceed to the next step
After I heard about Firebase, I decided it was a good idea to try it on my little Unity game.
I readed the documentation, followed the "Get Started" configuration tutorials, and changed the authentication rules so everyone could insert data.
void Start()
{
// Set up the Editor before calling into the realtime database.
FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("https://magicast-bd2fc.firebaseio.com/");
Firebase.Auth.FirebaseAuth.DefaultInstance.StateChanged += DefaultInstance_StateChanged;
// Get the root reference location of the database.
DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
var u = new User();
u.email = "sdjkdsdksadjsad";
u.fb_id = "sakdsajdhasd";
u.username = "jadhsjahjsda";
reference.SetValueAsync(u);
}
This code does execute, but when I go to my Firebase Console, I see no data on the Database tab. I can't figure out what I am doing wrong, and the code gives no errors at all! What am I doing wrong?
This is my user class. It's basically a testing class, no big stuff:
public class User
{
public string username;
public string email;
public string fb_id;
public User()
{
}
public User(string username, string email, string fb_id)
{
this.username = username;
this.email = email;
this.fb_id = fb_id;
}
}
You can't call .set() on arbitrary objects to the Firebase Database, they must come under one of the following categories:
string
long
double
bool
Dictionary<string, Object>
List<Object>
Instead of
reference.SetValueAsync(u);
You need to call
string json = JsonUtility.ToJson(u);
reference.SetRawJsonValueAsync(json);
You are also not actually logging in any user. To log in an anonymous user, first go to the Firebase Console -> Authentication and turn on the 'Anonymous' switch. Then authenticate with the following code:
Firebase.Auth.FirebaseAuth auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
auth.SignInAnonymouslyAsync().ContinueWith(task => {
if (task.IsCanceled) {
Debug.LogError("SignInAnonymouslyAsync was canceled.");
return;
}
if (task.IsFaulted) {
Debug.LogError("SignInAnonymouslyAsync encountered an error: " + task.Exception);
return;
}
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
You are not authenticated and the default Firebase security rules require that auth != null.
See the docs for how to authenticate with Unity.
The creation of a user with email and password fails and I can't find the source of the problem.
I'm using "Firebase Unity SDK" with the auth and database packages.
I followed this tutorial on the Firebase web page.
This is the C# code I use in my Unity project.
using UnityEngine;
using Firebase.Auth;
public class FirebaseAuthEmail : MonoBehaviour
{
public string email = "abc#gmail.com";
public string password = "abccbe123321";
void Start()
{
FirebaseAuth auth = FirebaseAuth.DefaultInstance;
auth.CreateUserWithEmailAndPasswordAsync(email, password).ContinueWith(
task => {
if (!task.IsCanceled && !task.IsFaulted)
{
// User created
Debug.Log("User created");
}
else
{
// User creation failed
Debug.Log("User creation failed");
}
if (task.IsCanceled) { Debug.Log("Task canceled"); }
if (task.IsFaulted) { Debug.Log("Task faulted"); }
});
}
}
When I press the play button i get "User creation failed" and "Task faulted".
I've successfully managed to add entries to the database but not to create an authenticated user.
And yes I've enabled Email/Password in the Firebase console.
Thanks in advance
Firebase Auth doesn't work on Unity Editor.
https://github.com/firebase/quickstart-unity/issues/3