使用自定义服务器实现Expo OTA更新时fetchUpdateAsync下载失败
自定义Expo OTA更新服务器结合EAS Build时fetchUpdateAsync失败问题
背景与问题
为规避EAS Update的1000次免费更新上限,使用官方提供的自定义更新服务器实现OTA更新,结合EAS Build构建应用。目前checkForUpdateAsync()能成功检测到更新,但调用fetchUpdateAsync()时触发错误,错误信息为*"Failed to download new update"*,已通过Sentry捕获该错误。
关键配置信息
app.json 更新配置
"updates": { "enabled": true, "checkAutomatically": "ON_LOAD", "url": "https://custom-domain.com/api/manifest", "codeSigningCertificate": "./code-signing/certificate.pem", "codeSigningMetadata": { "keyid": "main", "alg": "rsa-v1_5-sha256" } }, "runtimeVersion": { "policy": "sdkVersion" }
App.tsx 更新检测逻辑
useEffect(() => { checkForUpdates(); }, []); async function checkForUpdates() { try { const update = await Updates.checkForUpdateAsync(); if (update.isAvailable) { await Updates.fetchUpdateAsync(); // 触发错误 await Updates.reloadAsync(); } } catch (err) { console.log(err); } }
eas.json 构建配置
{ "cli": { "version": ">= 3.1.1" }, "build": { "development": { "channel": "development", "developmentClient": true, "distribution": "internal" }, "staging": { "distribution": "internal", "channel": "staging", "env": { "API_URL": "https://staging.domain.com", "EXPO_APPLE_ID": "APPLE_ID" } }, } }
更新流程
- 构建应用:执行
eas build -p ios --profile staging,构建完成后可通过二维码在设备安装应用。 - 修改应用内容(如页面标题)。
- 生成并部署更新:在自定义服务器目录执行
npm run expo-publish,该命令会执行expo export --experimental-bundle并将dist目录复制到服务器/updates目录。 - 重启应用:强制退出并重启应用后,应用会向自定义服务器请求更新,检测到更新后触发下载失败。
排查建议
- 验证静态资源可访问性:直接在浏览器访问服务器
/updates目录下的bundle文件和资源文件,确认能正常下载,若返回404/403则说明路径或权限配置错误。 - 核对manifest字段:检查自定义服务器返回的manifest中,
bundleURL和assets数组的资源路径是否与服务器实际文件路径完全一致,注意大小写、文件后缀(如.jsbundle)是否匹配。 - 检查代码签名一致性:确保应用端配置的公钥(
codeSigningCertificate)与生成更新时使用的私钥配对,签名不匹配会导致更新被客户端拒绝。 - 确认服务器CORS配置:自定义服务器需允许应用域名的跨域请求,否则客户端会拦截bundle和资源的下载请求。
- 查看服务器日志:检查自定义服务器的访问日志,查看
fetchUpdateAsync发起的请求状态码,根据状态码定位具体错误(如500表示服务器内部错误)。 - 对比EAS Update的manifest结构:将自定义服务器返回的manifest与EAS Update正常返回的manifest对比,确认是否缺少必要字段(如
id、createdAt)或字段格式不符合要求。
内容的提问来源于stack exchange,提问作者blouuuu
相关产品推荐
相关产品推荐

