📋 问题清单
1. EAS Build 配置错误
问题:
eas.json is not valid. - "update" is not allowed
原因: 中使用了不支持的
eas.json 和
update 字段
channel
解决方案:
删除 中的
eas.json 块删除
update 和
build.preview.android 中的
build.production.android 字段
channel
2. EAS Build 下载命令参数错误
问题:
Unexpected arguments: --latest, --output, ./app-release.apk
原因: 命令不支持这些参数
eas build:download
解决方案:
从 输出中提取下载 URL使用
eas build 或
curl 直接下载 APK
wget
DOWNLOAD_URL=$(echo "$BUILD_OUTPUT" | grep -oE 'https://expo.dev/artifacts/eas/[a-zA-Z0-9]+.apk' | head -1)
curl -L -o ./app-release.apk "$DOWNLOAD_URL"
3. 上传时请求体大小超限
问题:
EXCEED_MAX_PAYLOAD_SIZE
请求体大小超过限制。云函数请求体最大限制:文本类型请求体 100KB,其他类型请求体 6MB
原因:
APK 文件 111MB,Base64 编码后约 148MB即使分片上传,单个分片 Base64 编码后也超过限制
解决方案:
将分片大小从 5MB → 4MB → 3MB → 2MB(最终方案)缩短 JSON 字段名( →
uploadId,
u →
chunkIndex 等)使用
i +
application/octet-stream 避免被识别为文本类型
X-Content-Format: json
最终配置:
分片大小:2MB(二进制)Base64 编码后:约 2.67MB加上 JSON 字段:约 2.7MB(在 6MB 限制内)
4. 云函数存储 API 调用错误
问题:
app.storage is not a function
原因: v3.0.0+ 的 API 变更
@cloudbase/node-sdk
解决方案:
使用 而不是
app.uploadFile()使用
app.storage().uploadFile() 而不是
app.getTempFileURL()使用
app.storage().getTempFileURL() 而不是
app.deleteFile()更新
app.storage().deleteFile() 到
cloud-function/package.json
@cloudbase/node-sdk: ^3.0.0
5. 分片合并时文件路径错误
问题:
无法获取分片 0 的下载 URL (Error code: STORAGE_FILE_NONEXIST)
原因: 需要使用
getTempFileURL 格式的
cloud://,而不是普通路径
fileID
解决方案:
使用 格式例如:
cloud://<envId>.<storageDomain>/<path>创建
cloud://cloud1-4g5pq61cd6f19.636c-cloud16f19-1259499058/temp_chunks/upload_xxx/chunk_0 辅助函数统一转换
pathToCloudFileID
6. 云函数 3 秒超时限制
问题:
FUNCTION_TIME_LIMIT_EXCEEDED
Invoking task timed out after 3 seconds
原因:云函数最多执行 3 秒,无法在函数内完成下载和合并 56 个分片
解决方案:
方案1(当前使用):返回分片 URL 列表,客户端下载并合并方案2(已实现但未使用):创建异步任务,后台处理合并
当前实现:
// 云函数返回分片 URL 列表
return {
code: 0,
data: {
chunkUrls: [url1, url2, ...], // 所有分片的下载 URL
targetFilePath: filePath,
}
};
// 客户端下载并合并
const chunkFiles = await downloadAllChunks(chunkUrls);
const apkUri = await mergeChunks(chunkFiles);
7. 优先从 EAS 下载的实现
需求:优先从 EAS Build 下载,失败则从腾讯云下载
解决方案:
GitHub Actions:将 EAS 下载地址传递给上传脚本
EAS_DOWNLOAD_URL: ${{ steps.build.outputs.download_url }}
上传脚本:保存 EAS 下载地址到数据库
await saveVersionInfo(version, versionCode, cloudPath, uploadResult, easDownloadUrl);
云函数:返回 EAS 下载地址和腾讯云下载地址
{
easDownloadUrl: 'https://expo.dev/artifacts/...', // 优先使用
downloadUrl: 'https://...tcb.qcloud.la/...', // 备用
}
客户端:优先从 EAS 下载,失败则切换
if (updateInfo.easDownloadUrl) {
try {
return await downloadApkDirect(updateInfo.easDownloadUrl, onProgress);
} catch (easError) {
// 失败则从腾讯云下载
}
}
return await downloadApkDirect(updateInfo.downloadUrl, onProgress);
🎯 关键经验总结
1. 云函数限制
请求体大小:文本类型 100KB,其他类型 6MB执行时间:最多 3 秒解决方案:大文件分片上传,耗时操作客户端处理
2. TCB SDK API 变更
v3.0.0+:直接使用 等方法不要使用:
app.uploadFile()(已废弃)
app.storage().uploadFile()
3. 文件路径格式
getTempFileURL:必须使用 格式格式:
cloud://示例:
cloud://<envId>.<storageDomain>/<path>
cloud://cloud1-xxx.636c-cloud1-xxx-1259499058/path/to/file
4. 分片大小选择
2MB 是最佳选择(Base64 编码后约 2.67MB)3MB 可能超限(Base64 编码后约 4MB)建议:始终测试 Base64 编码后的实际大小
5. 错误处理策略
上传失败:自动重试(最多 3 次)下载失败:自动切换下载源(EAS → 腾讯云)合并失败:自动清理临时文件
📝 最佳实践
分片上传:文件 > 10MB 时使用分片上传分片大小:2MB(确保在云函数限制内)字段命名:使用短字段名减少 JSON 大小错误重试:每个分片最多重试 3 次下载策略:优先从 EAS 下载,失败则从腾讯云下载路径格式:统一使用 格式超时处理:耗时操作在客户端完成,云函数只返回必要信息
cloud://
🔧 相关文件
上传脚本:下载脚本:
scripts/upload-apk-to-tcb.js云函数:
scripts/download-and-merge-chunks.js更新服务:
cloud-function/index.jsGitHub Actions:
services/app-update.service.ts
.github/workflows/eas-build.yml
腾讯云服务器最新优惠活动:https://www.dunling.com/tengxunyun

















暂无评论内容