如何在不同场景之间保存firebase auth?

问题描述 投票:0回答:1

大家好,我是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.

c# firebase unity3d firebase-authentication
1个回答
1
投票

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;
}

1
投票

我想,这里可能有些混乱,因为我看到了一个对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");

应该就可以了。

希望能帮到你

--帕特里克

© www.soinside.com 2019 - 2024. All rights reserved.