Firebase短信验证请求OTP时打开浏览器,未上架Play无法用Play Integrity求助
Firebase Auth手机号验证问题(Unity)解决方案
一、Play Integrity API不用上架也能跑
别被误导了,Play Integrity API不需要游戏上架Google Play商店就能用,但得满足这几个条件:
- 必须用签名后的APK/AAB包测试,Unity编辑器直接跑或者未签名的调试包不行
- Google Cloud控制台要配置对:
- 确认Firebase项目和Google Cloud项目是关联的(Firebase后台「项目设置」里能看到关联状态)
- 给你的应用包名开了Play Integrity API,而且最新的
google-services.json已经替换到Unity项目的Assets根目录 - 签名用的SHA-256密钥,既要加到Firebase项目,也要加到Google Play Console的「应用签名」里(哪怕没上架,先在Play Console创建个空应用就行)
二、OTP请求跳浏览器?这么搞定
Firebase Auth跳浏览器是因为没法自动完成验证/短信检索,按步骤修复:
1. 补全短信检索依赖
在Unity的Assets/Plugins/Android文件夹里,确保有play-services-auth-api-phone和play-services-sms-retriever的aar包。可以用Firebase Unity SDK的依赖管理器自动导入,也能手动添加。
2. 修改AndroidManifest.xml
在Assets/Plugins/Android/AndroidManifest.xml里添加这些权限和服务:
<!-- 短信相关权限 --> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.SEND_SMS" /> <!-- 短信检索接收器 --> <receiver android:name="com.google.firebase.auth.api.phone.internal.SmsRetriever" android:exported="true"> <intent-filter> <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" /> </intent-filter> </receiver>
3. 优化验证代码
几个关键细节:
- 手机号必须带国家码(比如
+86),否则验证大概率失败 - 补全登录逻辑,打印完整错误信息方便排查
- 保存会话ID和重发令牌,支持手动验证和重发验证码
修改后的代码:
using Firebase; using Firebase.Auth; using TMPro; using UnityEngine; // 修正类名拼写:FIrebaseAuth → FirebaseAuth public class FirebaseAuth : MonoBehaviour { public TMP_InputField phoneNumberInputField; public TMP_InputField codeInputField; // 新增验证码输入框 private FirebaseAuth auth; private uint timeOut = 60 * 1000; private string verificationId; private PhoneAuthProvider.ForceResendingToken resendToken; private void Start() { FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => { if (task.Exception != null) { Debug.LogError("Firebase初始化失败: " + task.Exception); return; } auth = FirebaseAuth.DefaultInstance; }); } public void SendVerificationCode() { string phoneNumber = phoneNumberInputField.text; // 强制添加国家码,根据目标地区调整 if (!phoneNumber.StartsWith("+")) { phoneNumber = "+86" + phoneNumber; } PhoneAuthProvider provider = PhoneAuthProvider.GetInstance(auth); provider.VerifyPhoneNumber(phoneNumber, timeOut, resendToken, verificationCompleted: (credential) => { // 自动验证成功,直接登录 auth.SignInWithCredentialAsync(credential).ContinueWith(signTask => { if (signTask.IsCompletedSuccessfully) { Debug.Log("用户登录成功"); // 此处跳转游戏主界面 } else { Debug.LogError("登录失败: " + signTask.Exception); } }); }, verificationFailed: (error) => { // 打印完整错误信息,精准排查问题 Debug.LogError("验证失败: " + error.DebugDescription); }, codeSent: (id, token) => { Debug.Log("验证码已发送,会话ID: " + id); verificationId = id; resendToken = token; // 显示验证码输入UI codeInputField.gameObject.SetActive(true); }, codeAutoRetrievalTimeOut: (id) => { Debug.Log("自动收验证码超时,请手动输入"); // 显示验证码输入UI codeInputField.gameObject.SetActive(true); }); } // 手动输入验证码后的验证方法 public void VerifyInputCode() { string inputCode = codeInputField.text.Trim(); if (string.IsNullOrEmpty(inputCode) || string.IsNullOrEmpty(verificationId)) return; PhoneAuthCredential credential = PhoneAuthProvider.GetCredential(verificationId, inputCode); auth.SignInWithCredentialAsync(credential).ContinueWith(task => { if (task.IsCompletedSuccessfully) { Debug.Log("手动验证成功,用户登录"); // 此处跳转游戏主界面 } else { Debug.LogError("验证码错误或验证失败: " + task.Exception); } }); } }
4. 签名配置必须匹配
Unity打包时,一定要用和Firebase后台添加的SHA密钥一致的签名文件。调试包用调试签名的SHA-1/SHA-256,正式包用发布签名的,两类密钥都要提前加到Firebase后台。
三、Play Integrity API没生效?按顺序排查
如果开了API还是不行,按以下步骤检查:
- 去Google Cloud控制台,搜索「Play Integrity API」,确认状态是「已启用」
- 检查Firebase后台「项目设置」→「应用」,包名、SHA-1/SHA-256都要完全匹配,且
google-services.json是最新下载的 - 打包用Release模式(Debug也可以,但必须签名),用真实设备测试,模拟器可能不支持自动检索功能
- 查看
verificationFailed回调里的完整错误日志,比如有没有API未启用、密钥不匹配的明确提示
内容的提问来源于stack exchange,提问作者Prashant Khandelwal
相关产品推荐
相关产品推荐

