如何无第三方包/插件实现Flutter Firebase OTP读取与自动填充
Flutter 对接 Firebase 无第三方插件实现 OTP 自动填充方案
完全不需要依赖sms_autofill、alt_sms_autofill这类第三方包,靠系统原生自带的API、Flutter内置能力+Firebase官方包就能实现,分双端逻辑处理即可:
前置依赖
- 仅保留Firebase官方维护的
firebase_core、firebase_auth依赖,这两个不属于第三方短信填充插件范畴 - 直接删除所有第三方短信自动填充相关的pub依赖
双端通用Flutter层基础配置
不管是Android还是iOS,首先给OTP输入框加上系统自动填充标识,这步是零原生代码实现自动填充的核心:
final TextEditingController _otpController = TextEditingController(); TextField( controller: _otpController, keyboardType: TextInputType.number, maxLength: 6, // 核心配置,告诉系统这个输入框要接收一次性验证码 autofillHints: const [AutofillHints.oneTimeCode], decoration: const InputDecoration(hintText: "请输入6位验证码"), )
加完这个配置,Android 8.0+、iOS 12+的系统会自动识别短信里的OTP,在输入法顶部弹出填充选项,用户点一下就能自动填,不需要写任何额外逻辑。Firebase默认下发的OTP短信格式完全符合双端系统的识别规则,不用修改短信模板。
Android端进阶适配(覆盖低版本+无感知自动填充)
如果要做Android 8.0以下版本兼容,或者实现不需要用户点提示的完全自动填充,直接对接Google官方的SMS Retriever API即可,不需要申请短信读权限,合规无风险:
- 打开app层级的
android/app/build.gradle,引入Play Services官方依赖:
dependencies { implementation "com.google.android.gms:play-services-auth:20.7.0" implementation "com.google.android.gms:play-services-auth-api-phone:18.1.0" }
- 在
MainActivity.kt同级目录下新建Sms监听工具类,启动SmsRetriever客户端,监听5分钟内的应用专属短信,用正则提取6位数字验证码后,通过MethodChannel传给Flutter层。Firebase下发的OTP短信会自动拼接你应用的签名哈希,能直接被SmsRetriever捕获,不需要额外改Firebase后台配置。 - Flutter层初始化MethodChannel,在调用
FirebaseAuth.verifyPhoneNumber发送验证码之前,调用原生方法启动监听,收到原生传回的验证码后直接赋值给_otpController.text,可以直接触发验证提交逻辑。 - 提前获取你应用签名对应的11位哈希值,配到Firebase控制台Android应用的SHA证书列表里即可。
踩坑提示:绝对不要申请
READ_SMS权限实现读短信,这个权限在各大应用商店审核都会被重点拦截,非默认短信应用基本过审无望,SMS Retriever和系统自动填充框架都不需要这个权限。
iOS端适配
iOS端不需要写任何原生代码,只要开一个配置就行:
- 用Xcode打开iOS项目,在Signing & Capabilities标签页添加Associated Domains能力,新增条目
webcredentials:你的Firebase项目默认域名(格式一般是[你的项目ID].firebaseapp.com,在Firebase Auth控制台可以查到) - 不需要其他额外配置,系统会自动识别Firebase下发的OTP短信,在输入法栏弹出填充选项。iOS 12以下的版本没有自动填充能力,这部分用户占比极低,不需要额外兼容。
验证逻辑说明
自动填充拿到验证码之后,正常走Firebase Auth的手机号验证流程即可,和用户手动输入验证码的逻辑没有区别:
Future<void> _submitOtp(String smsCode, String verificationId) async { final credential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smsCode, ); await FirebaseAuth.instance.signInWithCredential(credential); }
内容的提问来源于stack exchange,提问作者bidyut das
相关产品推荐
相关产品推荐

