Firebase Phone Auth测试正常,真实手机号提示BILLING_NOT_ENABLED求助
解决方案:Firebase OTP登录触发[BILLING_NOT_ENABLED]错误
问题核心
测试手机号(+911234567890)能正常完成流程,但真实手机号触发该错误,本质是Google Cloud/Firebase的政策更新:当前即使免费短信额度未用完,真实号码的OTP验证也强制要求绑定支付方式,这和你1-2年前使用的规则不同。
可行解决方法
1. 将真实手机号加入Firebase测试号码列表
测试号码不受账单限制,可直接走验证流程:
- 打开Firebase控制台,进入你的项目 > Authentication > Sign-in method > Phone
- 拉到页面底部的Test phone numbers区域,点击Add test phone number
- 输入你的真实手机号(带国家码,比如+86xxxxxxxxx),自定义一个OTP码(如123456)并保存
- 用该手机号登录时,Firebase会直接返回你设置的测试OTP,无需发送真实短信,也不会触发账单校验
2. 启用App Check调试模式(仅开发阶段)
临时绕过账单限制,用于本地开发测试:
- 在Module级别的
build.gradle中添加依赖:implementation 'com.google.firebase:firebase-appcheck-debug:16.0.0' - 在Application类或启动页的
onCreate方法中初始化调试提供者:FirebaseApp.initializeApp(this); FirebaseAppCheck.getInstance().installAppCheckProviderFactory( DebugAppCheckProviderFactory.getInstance()); - 运行APP后,在Logcat中找到调试令牌,复制到Firebase控制台 > App Check > Apps > 你的APP > Debug tokens,点击Add debug token粘贴保存
- 此方法可让开发环境下的Phone Auth请求正常通过,无需绑定支付方式
3. 替换为第三方免费OTP服务
如果需要长期测试真实号码,可选用国内免费短信服务(如阿里云、腾讯云的免费额度)替代Firebase Phone Auth:
- 集成第三方SDK,在手机号登录页调用其接口发送OTP
- 在OTP验证页调用第三方接口校验验证码有效性
- 验证通过后再创建Firebase用户(若需关联Firebase其他服务)
代码适配示例
在LoginPhoneNumberActivity.java中添加测试号码判断,跳过真实短信流程:
String phoneNumber = getIntent().getStringExtra("phoneNumber"); // 加入你的测试号和真实手机号 if (phoneNumber.equals("+911234567890") || phoneNumber.equals("+86你的真实手机号")) { Intent intent = new Intent(this, LoginOtpActivity.class); intent.putExtra("phoneNumber", phoneNumber); intent.putExtra("isTestNumber", true); startActivity(intent); } else { // 原有Firebase发送OTP逻辑 PhoneAuthOptions options = PhoneAuthOptions.newBuilder(mAuth) .setPhoneNumber(phoneNumber) .setTimeout(60L, TimeUnit.SECONDS) .setActivity(this) .setCallbacks(mCallbacks) .build(); PhoneAuthProvider.verifyPhoneNumber(options); }
在LoginOtpActivity.java中处理测试号码的验证逻辑:
boolean isTestNumber = getIntent().getBooleanExtra("isTestNumber", false); String phoneNumber = getIntent().getStringExtra("phoneNumber"); String inputOtp = otpEditText.getText().toString(); if (isTestNumber) { if (inputOtp.equals("123456")) { // 对应你设置的测试OTP Intent intent = new Intent(this, LoginUsernameActivity.class); intent.putExtra("phoneNumber", phoneNumber); startActivity(intent); } else { Toast.makeText(this, "验证码错误", Toast.LENGTH_SHORT).show(); } } else { // 原有Firebase OTP验证逻辑 PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, inputOtp); signInWithPhoneAuthCredential(credential); }
内容的提问来源于stack exchange,提问作者Parvanshu Sharma
相关产品推荐
相关产品推荐

