已设置内容类型仍无法向Firebase模拟器上传文件,求解决
Firebase存储模拟器上传文件报"Missing content type"问题排查
环境配置
- Firebase Tools版本:11.21.0
- 环境变量:
FIREBASE_STORAGE_EMULATOR_HOST=localhost:9199 - Maven依赖:
<dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-storage</artifactId> <version>2.17.1</version> </dependency>
代码实现
存储服务初始化
emulatorStorage = StorageOptions.newBuilder() .setProjectId(projectId) .setHost("http://localhost:9199") .setCredentials(NoCredentials.getInstance()) .build() .getService();
文件上传代码
byte[] compress = "test".getBytes(); Blob blob = emulatorStorage.create( BlobInfo.newBuilder(index, filename) .setContentType("text/plain") .build(), compress, Storage.BlobTargetOption.doesNotExist());
问题现象
执行上传后抛出异常:
com.google.cloud.storage.StorageException: Failed to parse multipart request body part. Missing content type. at com.google.cloud.storage.StorageException.translate(StorageException.java:163) at com.google.cloud.storage.spi.v1.HttpStorageRpc.translate(HttpStorageRpc.java:297) at com.google.cloud.storage.spi.v1.HttpStorageRpc.create(HttpStorageRpc.java:379) at com.google.cloud.storage.StorageImpl.lambda$internalCreate$2(StorageImpl.java:208) at com.google.api.gax.retrying.DirectRetryingExecutor.submit(DirectRetryingExecutor.java:103) at com.google.cloud.RetryHelper.run(RetryHelper.java:76) at com.google.cloud.RetryHelper.runWithRetries(RetryHelper.java:50) at com.google.cloud.storage.Retrying.run(Retrying.java:60) at com.google.cloud.storage.StorageImpl.run(StorageImpl.java:1476) at com.google.cloud.storage.StorageImpl.internalCreate(StorageImpl.java:205) at com.google.cloud.storage.StorageImpl.create(StorageImpl.java:151)
调试确认模拟器返回400错误:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request POST http://localhost:9199/upload/storage/v1/b/demo-project.appspot.com/o?ifGenerationMatch=0&projection=full&uploadType=multipart { "code" : 400, "message" : "Failed to parse multipart request body part. Missing content type." }
问题原因与解决方案
原因
这是Firebase Tools 11.21.0版本的存储模拟器与google-cloud-storage 2.x版本的兼容性问题:google-cloud-storage 2.x默认对小文件使用multipart类型上传,但旧版模拟器对这种请求的Content-Type解析存在bug,无法识别BlobInfo中设置的内容类型。
解决方案
提供三种可行方案,任选其一即可:
升级Firebase Tools版本
将Firebase Tools升级到12.0.0及以上版本,新版本已修复该multipart请求解析的bug,无需修改代码即可正常运行。强制使用可恢复上传(Resumable)
在上传时指定UploadType.RESUMPABLE,绕过multipart上传格式,修改后的代码如下:
import com.google.cloud.storage.UploadType; // ... byte[] compress = "test".getBytes(); Blob blob = emulatorStorage.create( BlobInfo.newBuilder(index, filename) .setContentType("text/plain") .build(), compress, Storage.BlobTargetOption.doesNotExist(), Storage.BlobWriteOption.uploadType(UploadType.RESUMPABLE));
- 切换到Firebase Admin SDK
使用Firebase Admin SDK替代google-cloud-storage SDK,Admin SDK对Firebase模拟器的适配性更好,避免此类兼容性问题。
内容的提问来源于stack exchange,提问作者candccoder
相关产品推荐
相关产品推荐

