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

Android UI测试后清除Firestore模拟器数据库遭遇404错误的问题

Android UI测试后清除Firestore模拟器数据库遭遇404错误的问题

我完全理解你的场景——在Android UI测试中用Firestore模拟器做测试,想在每个测试结束后清空数据库,curl调用本地模拟器API没问题,但自己用HttpURLConnection写的代码却返回404,已经配置了网络安全规则却还是不行。下面给你几个排查方向和解决方案:

1. 检查URL中特殊字符的转义问题

你代码里直接拼接的(default)是URL保留字符,curl会自动处理这类特殊字符,但Java的URL类在构造时可能没有正确转义,导致实际请求的路径和预期不符,这是很常见的404诱因。

你可以手动转义括号部分,修改URL构造的代码:

try {
    // 手动转义(default)为URL安全的格式
    String encodedDatabaseName = "(default)".replace("(", "%28").replace(")", "%29");
    String urlStr = "http://10.0.2.2:8080/emulator/v1/projects/" + projectId + "/databases/" + encodedDatabaseName + "/documents";
    url = new URL(urlStr);
} catch (MalformedURLException exception) {
    Log.e("URLError", Objects.requireNonNull(exception.getMessage()));
}

或者用URLEncoder做标准转义:

try {
    String databaseName = "(default)";
    String encodedDatabaseName = URLEncoder.encode(databaseName, StandardCharsets.UTF_8.name());
    String urlStr = "http://10.0.2.2:8080/emulator/v1/projects/" + projectId + "/databases/" + encodedDatabaseName + "/documents";
    url = new URL(urlStr);
} catch (MalformedURLException | UnsupportedEncodingException exception) {
    Log.e("URLError", Objects.requireNonNull(exception.getMessage()));
}

2. 确认测试代码拥有网络权限

即使配置了network_security_config,你的Android测试代码也需要INTERNET权限才能访问Firestore模拟器的API。请检查测试目录下的AndroidManifest.xml(src/androidTest/AndroidManifest.xml)是否添加了权限声明:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="你的测试包名">
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

很多时候主Manifest的权限不会自动继承到测试环境,所以需要显式声明。

3. 用OkHttp替代HttpURLConnection简化调试

HttpURLConnection的API比较繁琐,对特殊字符的处理也容易出问题,推荐用OkHttp来发送请求,它会自动处理URL编码,还能更方便地获取详细的错误响应:

首先在Module级别的build.gradle中添加测试依赖:

androidTestImplementation("com.squareup.okhttp3:okhttp:4.12.0")

然后修改tearDown方法:

@After
public void tearDown() {
    String projectId = "test";
    OkHttpClient client = new OkHttpClient();
    String url = "http://10.0.2.2:8080/emulator/v1/projects/" + projectId + "/databases/(default)/documents";
    
    Request request = new Request.Builder()
            .url(url)
            .delete()
            .build();

    try (Response response = client.newCall(request).execute()) {
        Log.i("ResponseCode", "[Response Code: " + response.code() + "] msg: " + response.message());
        if (!response.isSuccessful()) {
            // 打印错误响应体,获取模拟器返回的具体错误原因
            String errorDetails = response.body() != null ? response.body().string() : "No error body";
            Log.e("TeardownError", "Failed to clear database: " + errorDetails);
        }
    } catch (IOException e) {
        Log.e("TeardownError", "Request failed", e);
    }
}

如果还是404,错误响应体里通常会有模拟器给出的具体提示,比如路径不存在,能帮你快速定位问题。

4. 对比curl和Android代码的请求细节

你可以启动Firestore模拟器时加上--debug参数,这样模拟器会打印所有收到的HTTP请求的完整细节(包括路径、请求头、方法等),然后对比curl发送的请求和Android代码发送的请求,就能直接看出两者的差异,比如路径是否一致、请求头是否缺失等。

举个启动模拟器的debug命令例子:

firebase emulators:start --only firestore --debug

备注:内容来源于stack exchange,提问作者akalanka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 11:42:58