firebase / firebase/firebase-tools
Unable to store file to emulator storage using google-cloud libraries: Failed to parse multipart request body part. Missing content type.
- Dominant language
- TypeScript
- Stars
- 4.5k
- Forks
- 1.3k
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 84
Description
### [REQUIRED] Environment info
**firebase-tools:11.21.0**
**Platform**
```
Distributor ID: Ubuntu
Description: Ubuntu 22.04.1 LTS
Release: 22.04
Codename: jammy
```
### [REQUIRED] Test case
FIREBASE_STORAGE_EMULATOR_HOST=localhost:9199
Create a basic maven project with google-cloud libs and start the emulator (after running firebase init).
Complete code example here;
https://github.com/gridcellcoder/firebase-emulator-debug
### [REQUIRED] Steps to reproduce
```
firebase-tools-linux emulators:start --project demo-project --debug
```
Then create a maven project only with latest cloud libs
```
com.google.api-client
google-api-client
2.1.3
com.google.cloud
google-cloud-storage
2.17.1
```
```
Storage emulatorStorage = StorageOptions.newBuilder()
.setProjectId("demo-project")
.setHost("http://localhost:9199")
.setCredentials(NoCredentials.getInstance())
.build()
.getService();
emulatorStorage.create(
BlobInfo.newBuilder("demo-project.appspot.com", "test")
.setContentType("text/plain")
.build()
,"test".getBytes(),
Storage.BlobTargetOption.doesNotExist());
```
results in an exception.
Other steps and approaches also indicated at stackoverflow:
https://stackoverflow.com/questions/75201025/unable-to-upload-media-file-tofirebase-emulator
tried with combinations of google-cloud-storage 2.15.0,2.16.0 and firebase-tools v11.19.0 ,v11.16.1 and get the same error message.
### [REQUIRED] Expected behavior
Storage of a text file in the emulated storage bucket `gs://demo-project.appspot.com` as seen in the UI.
### [REQUIRED] Actual behavior
```
Exception in thread "main" 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)
at org.example.Main.main(Main.java:17)
Caused by: 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."
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:118)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:37)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:570)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:493)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:603)
at com.google.cloud.storage.spi.v1.HttpStorageRpc.create(HttpStorageRpc.java:376)
... 9 more
```
[logfile.txt](https://github.com/firebase/firebase-tools/files/10474988/logfile.txt)
Contributor guide
Research direction
Start by reproducing the upload with the linked Maven example and the Firebase Storage emulator at localhost:9199, then inspect the emulator's multipart upload handling. Compare the request produced by google-cloud-storage with the expected multipart parts. Done means the text file is stored in the emulated bucket and appears in the UI without the missing-content-type error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- google-cloud, java, typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100