Flutter Web release模式Firebase手机号登录报captcha-check-failed错误
Flutter Web Release模式下Firebase Auth手机号验证报captcha-check-failed错误排查
问题现象
- 本地debug调试模式下功能运行正常:可正常弹出reCaptcha验证组件,完成验证流程后可正常下发OTP验证码
- 项目编译为release模式托管到GitHub Pages后:调用
signInWithPhoneNumber接口直接返回captcha-check-failed错误,且release环境下完全不会加载显示reCaptcha验证组件 - 已尝试移除
signInWithPhoneNumber的可选参数RecaptchaVerifier测试,问题未解决 - 错误截图:

当前功能实现代码
Future<void> loginWithPhoneRequestOTPWeb( WidgetRef ref, GlobalKey<FormState> formKey, String phoneNumber, ) async { try { EasyLoading.show(); await FirebaseAuth.instance .signInWithPhoneNumber( phoneNumber, RecaptchaVerifier( container: 'recaptcha', size: RecaptchaVerifierSize.compact, theme: RecaptchaVerifierTheme.dark, onError: (e) { print(e); EasyLoading.showError(e.message!); return; }, onExpired: () { print('Expired'); EasyLoading.showError('Session Expired'); return; }, onSuccess: () { EasyLoading.dismiss(); print('Captcha Success'); }, ), ) .then((ConfirmationResult result) { // update the verificationphone provider ref.read(sendOtpProvider(formKey).state).update((_) => true); ref.read(confirmationResultProvider(formKey).state).update((_) => result); EasyLoading.showSuccess(t!.otpSentSuccessfully); }); } on FirebaseAuthException catch (e) { if (e.code == 'invalid-phone-number') { print('The provided phone number is not valid.'); EasyLoading.showError('The provided phone number is not valid.'); } else if (e.code == 'too-many-requests') { print( 'You have exceeded the number of attempts allowed for this operation.'); EasyLoading.showError( 'You have exceeded the number of attempts allowed for this operation.'); } else { print(e.code.toString()); EasyLoading.showError(e.code.toString()); } } catch (e) { print(e.toString()); EasyLoading.showError(e.toString()); } }
排查与修复方案
1. 检查Firebase控制台授权域名配置
GitHub Pages的域名必须加入Firebase Auth的授权域名列表,否则reCaptcha校验会直接失败:
- 打开Firebase控制台 → 进入对应项目 → Authentication → Settings → Authorized domains
- 确认你的GitHub Pages域名(格式一般为
xxx.github.io,如果使用自定义域名也需要同步添加)已经在列表中,缺失则手动添加
注意:本地debug时默认使用的
localhost本身就在Firebase默认授权域名列表里,所以本地不会触发这个问题,这是debug正常release异常的最常见原因
2. 修复release模式下reCaptcha容器渲染问题
代码中指定了container: 'recaptcha',这个参数要求页面中必须存在一个id为recaptcha的DOM元素,Flutter Web release模式下渲染逻辑和debug模式有差异,很可能这个容器元素没有被正确创建/挂载:
- 打开项目
web/index.html文件,在<body>标签内、Flutter挂载节点(一般为<script src="flutter_bootstrap.js" async>之前)手动添加DOM容器:
<div id="recaptcha"></div>
- 如果不想手动维护容器,可以去掉
container参数,让Firebase Auth自动生成和挂载reCaptcha弹窗容器,避免容器不存在导致reCaptcha根本未加载。
3. 检查编译参数与Firebase初始化配置
- 确认release编译时没有开启过高等级的混淆导致Firebase Auth相关JS调用被截断,可先使用
flutter build web --web-renderer html --no-tree-shake-icons命令编译测试,排除canvaskit渲染器和tree-shake带来的兼容问题 - 确认release环境下Firebase的初始化参数(apiKey、authDomain、projectId等)和debug环境完全一致,不要在release环境下误用其他项目的初始化配置
- 部署后打开浏览器开发者工具的Console、Network面板,筛选
recaptcha、identitytoolkit相关请求,查看是否有资源加载被拦截、跨域报错的情况:GitHub Pages默认的CSP策略如果限制了外部脚本加载,会导致reCaptcha的JS脚本拉取失败,直接触发校验失败。
4. 临时验证方案
可以先把RecaptchaVerifier的size改成RecaptchaVerifierSize.normal,强制显式渲染reCaptcha组件,确认组件本身能正常加载后再调整为compact模式或者隐形模式。
内容的提问来源于stack exchange,提问作者Md. Sabik Alam Rahat
相关产品推荐
相关产品推荐

