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

无需启用明文HTTP,将Flutter Android应用连接到Firebase Auth模拟器

Flutter Firebase模拟器Android端Auth明文HTTP错误的替代解决方案

问题背景

我开发了一款基于Firebase后端的Flutter应用,调试阶段使用Firebase模拟器测试。为了让物理设备能连接开发机上的模拟器,做了以下配置:

  • 在firebase.json中设置模拟器的host为0.0.0.0,避免硬编码可变的本地IP
  • 在main.dart的kDebugMode分支中指定模拟器的局域网IP地址(通过Dart环境变量传递)

测试中发现:

  • Web版本能正常与Auth模拟器通信
  • Android物理设备或模拟器运行调试版本时,调用firebase_ui_auth的登录界面会抛出错误:
    com.google.firebase.FirebaseException: An internal error has occurred. [ Cleartext HTTP traffic to <my local ip> not permitted ]
    
  • 绕过认证功能后,Android应用可以正常连接Firestore模拟器

已知的常规解决方案是全局启用明文HTTP,或仅允许特定IP的明文流量,但我不想为本地测试全局开启明文,也不愿在Android XML中硬编码可变的本地IP,希望找到替代方案,比如让SDK通过HTTPS连接模拟器。目前临时方案是仅在debug版本的Android清单(android/app/src/debug)中全局启用明文HTTP。

替代方案

方案1:用HTTPS代理转发模拟器流量

通过搭建本地HTTPS代理,将Firebase Auth模拟器的HTTP请求转成HTTPS,这样Android应用就不会触发明文流量限制。

步骤:

  1. 生成自签名证书
    用openssl生成有效期1年的自签名证书:

    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
    

    填写信息时,Common Name可以设为自定义的本地域名,比如firebase-emulator.local。

  2. 搭建HTTPS代理
    用Caddy工具快速配置代理(无需复杂配置),创建Caddyfile:

    https://firebase-emulator.local {
        reverse_proxy http://localhost:9099  # Firebase Auth模拟器默认端口
        tls cert.pem key.pem
    }
    

    启动Caddy后,访问https://firebase-emulator.local就会转发到本地的Auth模拟器。

  3. 配置Android信任自签名证书

    • 将生成的cert.pem重命名为firebase_emulator_cert.pem,放到android/app/src/debug/res/raw/目录下
    • 在android/app/src/debug/res/xml/network_security_config.xml中添加信任配置:
      <?xml version="1.0" encoding="utf-8"?>
      <network-security-config>
          <base-config>
              <trust-anchors>
                  <certificates src="@raw/firebase_emulator_cert"/>
                  <certificates src="system"/>
              </trust-anchors>
          </base-config>
      </network-security-config>
      
    • 在debug版本的AndroidManifest.xml中指定该配置:
      <application
          ...
          android:networkSecurityConfig="@xml/network_security_config">
      
  4. 修改Flutter代码中的模拟器地址
    在kDebugMode分支中,将Auth模拟器地址改为https://firebase-emulator.local,同时在物理设备的hosts文件中映射该域名到开发机的局域网IP(或者用本地DNS服务解析)。

方案2:动态配置允许的IP(无需硬编码)

利用Android构建系统的变量替换功能,结合Flutter环境变量动态设置允许明文流量的IP,避免硬编码。

步骤:

  1. 创建debug专用的网络安全配置
    在android/app/src/debug/res/xml/network_security_config.xml中添加:

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config cleartextTrafficPermitted="true">
            <domain includeSubdomains="true">${LOCAL_IP}</domain>
        </domain-config>
    </network-security-config>
    
  2. 在build.gradle中注入环境变量
    修改android/app/build.gradle的buildTypes块,从环境变量中获取LOCAL_IP并替换到资源文件:

    android {
        ...
        buildTypes {
            debug {
                resValue "string", "LOCAL_IP", System.getenv("LOCAL_IP") ?: "10.0.2.2"
            }
        }
    }
    

    这里默认值10.0.2.2是Android模拟器访问主机的默认IP。

  3. 运行Flutter时传递局域网IP
    启动应用时通过环境变量指定你的开发机局域网IP:

    LOCAL_IP=192.168.1.100 flutter run --debug
    

    这样debug版本的Android应用只会允许该IP的明文流量,比全局启用更安全。

额外说明

Firestore模拟器能正常连接的原因是:Firebase Firestore SDK在调试模式下,内部对模拟器连接做了特殊处理,自动允许明文流量;而firebase_ui_auth依赖的Auth SDK没有这个逻辑,因此触发了Android的明文流量限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:25:13