所以,我正在制作的应用程序使用 firebase auth 进行注册和登录。注册成功,用户将被添加到 iPhone 和 Android 上的 Unity 编辑器中的 Firebase 控制台中。但登录仅适用于 Unity 编辑器和 iOS。它在 Android 上不起作用,我不知道为什么。我尝试了一切。我的登录代码与这里基本相同: https://github.com/misskaseyann/firebase-unity-auth/blob/master/Scripts/Authentication/SignInHandler.cs 唯一的区别在于显示 UI,因为我不在场景之间切换,而是启用不同的面板,例如:
void Start()
{
auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
signinButton.onClick.AddListener(() => {
SigninWithEmailAsync();
});
createAccountButton.onClick.AddListener(() => {
FindObjectOfType<LoginManagerScript>().LoginPanel.SetActive(false);
FindObjectOfType<LoginManagerScript>().RegisterPanel.SetActive(true);
});
}
android 上的signinButton.onClick 由于某种原因无法正常工作。即使我在侦听器中放置其他内容(例如调试),当我单击它时它也不会显示。但它在编辑器和 iPhone 上显示。我在这里做错了什么?当我打开应用程序时,ADB logcat 会这样说:
InvalidOperationException:在 CheckDependency 完成之前不要调用 Firebase 函数
我检查了应用程序包 ID,它与 Firebase 中的相同。奇怪的是,即使我按下登录按钮,似乎也没有发生任何事情。无论。为什么?
哟,我修好了。这可能是一种解决方法,而不是官方修复,但它对我有用。我制作了一个在应用程序启动时运行的场景,制作了一个“firebaseinit”游戏对象,并仅将此类用于 firebase init:
public class FirebaseINIT : MonoBehaviour
{
public static bool firebaseReady;
void Start()
{
CheckIfReady();
}
void Update()
{
if(firebaseReady == true)
{
SceneManager.LoadScene("LoginScene");
}
}
public static void CheckIfReady()
{
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
Firebase.DependencyStatus dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
Firebase.FirebaseApp app = Firebase.FirebaseApp.DefaultInstance;
firebaseReady = true;
Debug.Log("Firebase is ready for use.");
}
else
{
firebaseReady = false;
UnityEngine.Debug.LogError(System.String.Format(
"Could not resolve all Firebase dependencies: {0}", dependencyStatus));
}
});
}
}
现在它也适用于 Android。 Android 似乎存在依赖项加载或类似问题,并且没有及时加载依赖项。我可能可以把它放在我的主场景中,但这样更快。我希望这对一些人有帮助,因为我至少在弱者中挣扎过。
如果您不介意,我会尝试在您的答案@sesmajster 周围添加更多上下文(并且在评论中要做的事情有点多)。
您的解决方法基本上是拨打
CheckAndFixDependenciesAsync
。其作用是,在 Android 上,Firebase 的许多功能都依赖于 Google Play Services (GPS)。此调用将确保 GPS 可用,并提示玩家升级 GPS(如果 GPS 已过时)。如果玩家决定不更新或拥有无法访问 GPS 的设备(在美国,最常见的是 Kindle 平板电脑或 VR 耳机),您将获得 DependencyStatus.Unavailable
结果,您可以采取进一步行动。请注意,在 Android 上,GPS 并不是普遍需要的——将来可能不需要此调用。
在桌面平台(MacOS、Windows 和 Linux - 最常见的是在 Unity 编辑器中进行开发时)和 iOS 中,没有等效的外部依赖项。此调用在那里是可选的,但仍然推荐,以防万一出现。
对于您的回答,我将建议进行一项额外的更改。你所做的有点不安全,
firebaseReady
应该标记为volatile
,你也可以比轮询每一帧更好一点。我确信您已经意识到 ContinueWith
在后台线程上触发,并且可能会在 Unity 中导致一些问题,但是 Firebase 提供了一个扩展方法 ContinueWithOnMainThread
可以简化您的代码,如下所示:
public class FirebaseINIT : MonoBehaviour
{
void Start()
{
CheckIfReady();
}
public static void CheckIfReady()
{
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
Firebase.DependencyStatus dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
Firebase.FirebaseApp app = Firebase.FirebaseApp.DefaultInstance;
SceneManager.LoadScene("LoginScene");
Debug.Log("Firebase is ready for use.");
}
else
{
UnityEngine.Debug.LogError(System.String.Format(
"Could not resolve all Firebase dependencies: {0}", dependencyStatus));
}
});
}
}
(您也可以选择
async
/await
或使用协程,但我认为最好符合您当前的风格)。我在这篇博文和这个视频中更详细地介绍了这一点。
我按如下方式修复了这个问题; 每次我需要向 Firebase 发送某些内容(例如事件)时,我都会编写一个函数并在该函数中传递事件调用,如下所示:
首先,编写接受字符串作为输入的函数:
public static void CheckIfReady(字符串消息) {
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
Firebase.DependencyStatus dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
Firebase.FirebaseApp app = Firebase.FirebaseApp.DefaultInstance;
Debug.Log("Firebase is ready for use.");
FirebaseAnalytics.LogEvent(message);
}
else
{
UnityEngine.Debug.LogError(System.String.Format(
"Could not resolve all Firebase dependencies: {0}", dependencyStatus));
}
});
}
然后,您可以通过输入事件调用此函数,如下所示:
CheckIfReady("你的 LogEvent 放在这里...");
就是这样,没有更多错误。