Firebase Auth无法获取特定ErrorCode问题及REST API替代方案咨询
看起来你在Unity里使用Firebase Auth做邮箱密码登录时,不管输入错误密码还是无效邮箱,都只能拿到通用的AuthError.Failure(错误码1),没法获取具体的错误类型对吧?我之前也碰到过类似的情况,给你几个可能的解决思路,以及如果SDK确实有问题时的REST API替代方案:
一、修复Firebase SDK错误码获取问题
首先排查是不是SDK版本或者异常处理方式的问题:
更新Firebase SDK到最新稳定版
旧版本的Unity Firebase Auth SDK确实存在错误码映射不全的问题,建议你打开Package Manager,找到Firebase Auth包,更新到官方最新的稳定版本,很多这类问题在新版本里已经修复了。修改异常捕获的类型
你当前捕获的是FirebaseException,但在Unity的Firebase Auth中,登录相关的异常其实是FirebaseAuthException(属于FirebaseException的子类),直接捕获这个子类能拿到更准确的错误码。修改后的代码如下:
await _auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task => { if (task.IsFaulted) { foreach (Exception exception in task.Exception.Flatten().InnerExceptions) { if (exception is FirebaseAuthException authException) { UnityEngine.Debug.Log($"Error code: {authException.ErrorCode}, Message: {authException.Message}"); // 这里可以直接根据AuthError枚举判断具体错误,比如AuthError.WrongPassword、AuthError.InvalidEmail等 } } } });
如果还是不行,你可以尝试打印异常的完整堆栈信息,看看有没有更深层的InnerException包含具体错误码,有时候异常嵌套的层数比你想象的多。
- 检查项目配置
确保你的Unity项目已经正确配置了Firebase,包括google-services.json(Android)或GoogleService-Info.plist(iOS)文件已经正确导入,并且包名/Bundle ID和Firebase控制台里的配置一致。配置错误也可能导致错误码无法正确映射。
二、使用Firebase Auth REST API替代实现
如果上面的方法都没用,确实是SDK本身的问题,那可以直接调用Firebase的REST API来实现登录,这样能拿到最准确的错误信息。
1. 核心请求说明
Firebase Auth的登录端点是:https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=你的API_KEY
- 请求方式:POST
- 请求头:
Content-Type: application/json - 请求体是JSON格式,包含邮箱、密码和
returnSecureToken字段(设为true才能拿到令牌)
2. Unity中的实现代码
你可以用UnityWebRequest来发送请求,示例代码如下:
using UnityEngine; using UnityEngine.Networking; using System.Collections; using System.Text; public class FirebaseAuthRESTHelper : MonoBehaviour { // 替换成你Firebase项目的Web API Key(在Firebase控制台的项目设置里可以找到) private const string FIREBASE_API_KEY = "your-web-api-key-here"; private const string SIGN_IN_ENDPOINT = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={0}"; // 调用这个协程来执行登录 public IEnumerator SignInWithEmailPassword(string email, string password) { string requestUrl = string.Format(SIGN_IN_ENDPOINT, FIREBASE_API_KEY); // 构造请求体 AuthRequest requestBody = new AuthRequest { email = email, password = password, returnSecureToken = true }; string jsonBody = JsonUtility.ToJson(requestBody); byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonBody); using (UnityWebRequest request = new UnityWebRequest(requestUrl, "POST")) { request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { // 解析成功响应 AuthSuccessResponse successResponse = JsonUtility.FromJson<AuthSuccessResponse>(request.downloadHandler.text); Debug.Log($"登录成功!用户ID: {successResponse.localId}, ID令牌: {successResponse.idToken}"); // 这里可以把令牌存储起来用于后续的身份验证 } else { // 解析错误响应 AuthErrorResponse errorResponse = JsonUtility.FromJson<AuthErrorResponse>(request.downloadHandler.text); Debug.Log($"错误码: {errorResponse.error.code}, 错误信息: {errorResponse.error.message}"); // 根据错误码处理不同的用户提示 switch (errorResponse.error.code) { case 400: // 子错误需要从message里判断,或者解析errors数组 if (errorResponse.error.message.Contains("INVALID_EMAIL")) { Debug.Log("请输入有效的邮箱地址"); } else if (errorResponse.error.message.Contains("INVALID_PASSWORD")) { Debug.Log("密码错误,请重试"); } else if (errorResponse.error.message.Contains("USER_NOT_FOUND")) { Debug.Log("该邮箱未注册"); } else if (errorResponse.error.message.Contains("USER_DISABLED")) { Debug.Log("该账号已被禁用"); } break; default: Debug.Log("登录失败,请稍后重试"); break; } } } } // 用于序列化请求和响应的辅助类 [System.Serializable] private class AuthRequest { public string email; public string password; public bool returnSecureToken; } [System.Serializable] private class AuthSuccessResponse { public string idToken; public string email; public string refreshToken; public string expiresIn; public string localId; } [System.Serializable] private class AuthErrorResponse { public ErrorDetails error; } [System.Serializable] private class ErrorDetails { public int code; public string message; public ErrorInfo[] errors; } [System.Serializable] private class ErrorInfo { public string message; public string domain; public string reason; } }
3. 常见错误码说明
REST API返回的错误码中,常见的登录相关错误都包含在400状态码下,通过error.message或error.errors[0].reason可以区分具体类型:
INVALID_EMAIL: 邮箱格式无效INVALID_PASSWORD: 密码错误USER_NOT_FOUND: 邮箱未注册USER_DISABLED: 账号被管理员禁用TOO_MANY_ATTEMPTS_TRY_LATER: 登录尝试次数过多,暂时锁定
内容来源于stack exchange

