You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用首次启动Google reCAPTCHA v3初始化失败问题求助

问题诊断与解决方案

核心问题分析

  1. 重复初始化冲突:你在PROJECTApp中同时初始化了两个独立的RecaptchaClient实例(一个在ReCaptchaProjectClient的init方法里,另一个在initRecaptchaClient方法里),异步初始化的竞态可能导致首次启动时其中一个实例初始化失败,进而触发"Invalid site Key"错误(实际是初始化未完成的误报)。
  2. 异步初始化未等待完成:executeRegisterAction仅通过::recaptchaClient.isInitialized判断状态,但首次启动时initializeRecaptchaClient的协程可能还未执行完成,此时调用execute会直接返回null,同时触发未初始化的报错。
  3. 首次启动网络时机问题:Recaptcha.fetchClient需要网络请求验证站点密钥,Application的onCreate阶段系统可能限制网络请求优先级,导致首次启动时验证请求超时或失败,重启后网络状态稳定,验证成功。

修复步骤

1. 移除重复初始化,统一管理客户端实例

删除PROJECTApp中的重复初始化逻辑,仅通过ReCaptchaProjectClient管理唯一的客户端实例:

class PROJECTApp : Application(), CoroutineScope {
    lateinit var reCaptchaProjectClient: ReCaptchaProjectClient
    private val job = Job()

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

    override fun onCreate() {
        super.onCreate()
        FirebaseApp.initializeApp(this)
        reCaptchaProjectClient = ReCaptchaProjectClient(this, this)
    }

    override fun onTerminate() {
        super.onTerminate()
        job.cancel()
    }
}

2. 增加初始化状态监听与重试机制

修改ReCaptchaProjectClient,用StateFlow跟踪初始化状态,初始化失败时自动重试,确保客户端就绪后再执行验证:

class ReCaptchaProjectClient(private val coroutineScope: CoroutineScope, private val application: Application) {
    private val _initializationState = MutableStateFlow<RecaptchaClient?>(null)
    val initializationState: StateFlow<RecaptchaClient?> = _initializationState

    init {
        initializeRecaptchaClient()
    }

    private fun initializeRecaptchaClient(retryCount: Int = 3) {
        coroutineScope.launch(Dispatchers.IO) {
            try {
                val client = Recaptcha.fetchClient(application, "recaptchaSiteKey")
                _initializationState.value = client
            } catch (e: Exception) {
                Log.e("ReCaptcha123", "Initialization failed, retry left: ${retryCount-1}", e)
                if (retryCount > 0) {
                    delay(1000) // 延迟1秒后重试
                    initializeRecaptchaClient(retryCount - 1)
                } else {
                    _initializationState.value = null
                }
            }
        }
    }

    fun executeRegisterAction(onTokenReceived: (String?) -> Unit) {
        coroutineScope.launch {
            val client = initializationState.firstOrNull { it != null } ?: run {
                onTokenReceived(null)
                return@launch
            }
            try {
                val token = client.execute(RecaptchaAction.SIGNUP)
                onTokenReceived(token.toString().removePrefix("Success(").removeSuffix(")"))
            } catch (e: Exception) {
                Log.e("ReCaptcha123", "Execute failed", e)
                onTokenReceived(null)
            }
        }
    }
}

3. 调整初始化时机(可选)

如果首次启动网络限制仍存在,可将初始化延迟到应用进入前台时执行,结合ProcessLifecycleOwner监听:

// 在ReCaptchaProjectClient的init中替换为:
init {
    coroutineScope.launch {
        ProcessLifecycleOwner.get().lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
            initializeRecaptchaClient()
        }
    }
}

需要添加依赖:

implementation "androidx.lifecycle:lifecycle-process:2.6.2"

额外注意事项

  • 确保AndroidManifest.xml中声明了INTERNET权限:
    <uses-permission android:name="android.permission.INTERNET" />
    
  • 确认站点密钥是Android平台专用的reCAPTCHA v3密钥,而非Web或iOS密钥。
  • 避免在主线程执行网络相关操作,Recaptcha.fetchClient本身是挂起函数,建议在Dispatchers.IO调度器中执行。

内容的提问来源于stack exchange,提问作者AM1379

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 02:37:28