大家好,我是Unity和C#的新手,我有这个脚本来创建登录用户,并在firebase数据库中发布(与电子邮件和密码).我从youtube教程中复制了它,并做了一点修改。
using System.Collections;
using System.Collections.Generic;
using FullSerializer;
using Proyecto26;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using Firebase.Auth;
public class PlayerScores : MonoBehaviour
{
public Text scoreText;
public InputField getScoreText;
public InputField emailText;
public InputField usernameText;
public InputField passwordText;
private System.Random random = new System.Random();
User user = new User();
private string databaseURL = "testingurl";
private string AuthKey = "testingapikey";
public static fsSerializer serializer = new fsSerializer();
public static int playerScore;
public static string playerName;
private string idToken;
public static string localId;
private string getLocalId;
private void Start()
{
playerScore = random.Next(0, 101);
scoreText.text = "Score: " + playerScore;
}
public void OnSubmit()
{
PostToDatabase();
Debug.Log("datos subidos a database");
}
public void OnGetScore()
{
GetLocalId();
}
private void UpdateScore()
{
scoreText.text = "Score: " + user.userScore;
}
private void PostToDatabase(bool emptyScore = false, string idTokenTemp = "")
{
if (idTokenTemp == "")
{
idTokenTemp = idToken;
}
User user = new User();
if (emptyScore)
{
user.userScore = 0;
}
RestClient.Put(databaseURL + "/" + localId + ".json?auth=" + idTokenTemp, user);
}
private void RetrieveFromDatabase()
{
RestClient.Get<User>(databaseURL + "/" + getLocalId + ".json?auth=" + idToken).Then(response =>
{
user = response;
UpdateScore();
});
}
public void SignUpUserButton()
{
SignUpUser(emailText.text, usernameText.text, passwordText.text);
}
public void SignInUserButton()
{
SignInUser(emailText.text, passwordText.text);
}
private void SignUpUser(string email, string username, string password)
{
string userData = "{\"email\":\"" + email + "\",\"password\":\"" + password + "\",\"returnSecureToken\":true}";
RestClient.Post<SignResponse>("https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=" + AuthKey, userData).Then(
response =>
{
string emailVerification = "{\"requestType\":\"VERIFY_EMAIL\",\"idToken\":\"" + response.idToken + "\"}";
RestClient.Post(
"https://www.googleapis.com/identitytoolkit/v3/relyingparty/getOobConfirmationCode?key=" + AuthKey,
emailVerification);
localId = response.localId;
playerName = username;
PostToDatabase(true, response.idToken);
Debug.Log("SingUp Correcto");
}).Catch(error =>
{
Debug.Log("falta email/password");
Debug.Log(error);
});
}
private void SignInUser(string email, string password)
{
string userData = "{\"email\":\"" + email + "\",\"password\":\"" + password + "\",\"returnSecureToken\":true}";
RestClient.Post<SignResponse>("https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=" + AuthKey, userData).Then(
response =>
{
string emailVerification = "{\"idToken\":\"" + response.idToken + "\"}";
RestClient.Post(
"https://www.googleapis.com/identitytoolkit/v3/relyingparty/getAccountInfo?key=" + AuthKey,
emailVerification).Then(
emailResponse =>
{
fsData emailVerificationData = fsJsonParser.Parse(emailResponse.Text);
EmailConfirmationInfo emailConfirmationInfo = new EmailConfirmationInfo();
serializer.TryDeserialize(emailVerificationData, ref emailConfirmationInfo).AssertSuccessWithoutWarnings();
if (emailConfirmationInfo.users[0].emailVerified)
{
idToken = response.idToken;
localId = response.localId;
GetUsername();
Debug.Log("Login Correcto");
SceneManager.LoadScene("SignInEdit"); //para logear correctamente solo necesita que el email y password sean correctos, el username no importa.
}
else
{
Debug.Log("You are stupid, you need to verify your email dumb");
}
});
}).Catch(error =>
{
Debug.Log(error);
});
}
private void GetUsername()
{
RestClient.Get<User>(databaseURL + "/" + localId + ".json?auth=" + idToken).Then(response =>
{
playerName = response.userName;
});
}
private void GetLocalId()
{
RestClient.Get(databaseURL + ".json?auth=" + idToken).Then(response =>
{
var username = getScoreText.text;
fsData userData = fsJsonParser.Parse(response.Text);
Dictionary<string, User> users = null;
serializer.TryDeserialize(userData, ref users);
foreach (var user in users.Values)
{
if (user.userName == username)
{
getLocalId = user.localId;
RetrieveFromDatabase();
break;
}
}
}).Catch(error =>
{
Debug.Log(error);
});
}
}
我的问题是我不能在场景之间保存我的firebase登录名,当我改变场景时,我不能再与我的firebase数据库进行交互.我试着做了一个dontdestroyonload脚本,并添加了一个包含我的PlayerScore脚本的unity gameobject,但没有成功。
我读到的是需要将我的userid存储在一个静态变量中,以便在任何地方调用它,但我不知道怎么做,因为我是c#编码的新手。
Can someone give some guidance?, thanks.PS: the script of above need another 3 script to works, where storeget some values.If is necessary I add them.
Firebase SDK会自动持久化认证状态,并尝试自动恢复它。你只需要写代码来拾取它,这涉及到附加一个监听器到auth状态。
请看Firebase文档中的第一个片段,内容为 获取当前登录的用户:
建议通过在Auth对象上设置一个监听器来获取当前用户。
Firebase.Auth.FirebaseAuth auth; Firebase.Auth.FirebaseUser user; // Handle initialization of the necessary firebase modules: void InitializeFirebase() { Debug.Log("Setting up Firebase Auth"); auth = Firebase.Auth.FirebaseAuth.DefaultInstance; auth.StateChanged += AuthStateChanged; AuthStateChanged(this, null); } // Track state changes of the auth object. void AuthStateChanged(object sender, System.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("Signed in " + user.UserId); } } } void OnDestroy() { auth.StateChanged -= AuthStateChanged; auth = null; }
我想,这里可能有些混乱,因为我看到了一个对Auth对象的引用。官方Firebase Unity SDK 与原始REST调用混合在一起的 RestClient. 我会回答这个问题,假设你可以使用的是 Unity SDK. 这比试图手动使用Firebase SDK要简单得多(并且可以得到很好的好处--比如本地缓存)。
1) Firebase认证
一旦Firebase认证被初始化。FirebaseAuth.DefaultInstance.CurrentUser
将始终包含您当前登录的用户或 null
如果用户没有登录。这个值实际上存储在C++中,并通过C#访问,这意味着它实际上并不了解或遵守Unity的典型对象生命周期。这意味着,一旦你签入了一个用户,这个值将始终保持当前用户,而不需要跨场景边界持久化。事实上,这个值甚至会在你的游戏运行过程中被保存下来(这意味着你的玩家不必每次都要登录)。
不过需要提醒的是,这个值是异步更新的。CurrentUser
是异步更新的 -- 也就是说,并不能真正保证 CurrentUser
是最新的 -- 所以一般来说,注册一个新的产品是安全的。StateChanged
听者 从文件中:
Firebase.Auth.FirebaseAuth auth;
Firebase.Auth.FirebaseUser user;
// Handle initialization of the necessary firebase modules:
void InitializeFirebase() {
Debug.Log("Setting up Firebase Auth");
auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
auth.StateChanged += AuthStateChanged;
AuthStateChanged(this, null);
}
// Track state changes of the auth object.
void AuthStateChanged(object sender, System.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("Signed in " + user.UserId);
}
}
}
void OnDestroy() {
auth.StateChanged -= AuthStateChanged;
auth = null;
}
我强烈建议观看我的 Firebase认证教程 来看看我是如何考虑将其与游戏整合的。的 分享链接 是合适的,但我对你代码中的各种REST调用有点好奇。
如果您使用的是 Firebase Unity SDK, 电子邮件密码认证 应该像创建用户和
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.
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("Firebase user created successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
创建一个用户和
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;
}
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
来签到。也就是说,应该不需要使用 RestClient.
2)实时数据库
一旦你通过了身份验证,任何呼叫到 Firebase实时数据库SDK 将自动使用 CurrentUser
值(正如我之前提到的--它在SDK的C++端持续存在)。
如果你希望使用 规则来保护用户数据的安全 如:
{
"rules": {
"users": {
"$user_id": {
// grants write access to the owner of this user account
// whose uid must exactly match the key ($user_id)
".write": "$user_id === auth.uid"
}
}
}
}
那么 写数据:
Database.DefaultInstance.GetReference($"/users/{FirebaseAuth.DefaultInstance.CurrentUser.UserId}/mySecret").SetValueAsync("flowers");
应该就可以了。
希望能帮到你
--帕特里克