Skip to content

Commit be1bed8

Browse files
committed
feat(storage, md5hash): allow md5hash to be set on upload
metadata property md5hash is allowed for upload, just not for updateMetadata allow it to go through in the putNNN scenarios but screen for it on update
1 parent 1d3e946 commit be1bed8

File tree

4 files changed

+67
-7
lines changed

4 files changed

+67
-7
lines changed

packages/storage/e2e/StorageReference.e2e.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,10 @@ describe('storage() -> StorageReference', function () {
351351
const storageReference = firebase.storage().ref(WRITE_ONLY_NAME);
352352
const metadata = await storageReference.updateMetadata({
353353
contentType: 'image/jpeg',
354+
cacheControl: 'true',
355+
contentDisposition: 'disposed',
356+
contentEncoding: 'encoded',
357+
contentLanguage: 'martian',
354358
customMetadata: {
355359
hello: 'world',
356360
},
@@ -406,6 +410,19 @@ describe('storage() -> StorageReference', function () {
406410
// FIXME this is failing the part that fails
407411
should.equal(metadataAfterRemove.customMetadata.removeMe, undefined);
408412
});
413+
414+
it('should error if updateMetadata includes md5hash', async function () {
415+
const storageReference = firebase.storage().ref(WRITE_ONLY_NAME);
416+
try {
417+
await storageReference.updateMetadata({
418+
md5hash: '0xDEADBEEF',
419+
});
420+
return Promise.reject(new Error('Did not throw on invalid updateMetadata'));
421+
} catch (e) {
422+
e.message.should.containEql('md5hash may only be set on upload, not on updateMetadata');
423+
return Promise.resolve();
424+
}
425+
});
409426
});
410427

411428
describe('putFile', function () {
@@ -515,6 +532,21 @@ describe('storage() -> StorageReference', function () {
515532
return Promise.resolve();
516533
}
517534
});
535+
536+
it('allows valid metadata properties for upload', async function () {
537+
const storageReference = firebase.storage().ref(`${PATH}/metadataTest.txt`);
538+
await storageReference.putString('foo', 'raw', {
539+
contentType: 'text/plain',
540+
md5hash: '123412341234',
541+
cacheControl: 'true',
542+
contentDisposition: 'disposed',
543+
contentEncoding: 'encoded',
544+
contentLanguage: 'martian',
545+
customMetadata: {
546+
customMetadata1: 'metadata1value',
547+
},
548+
});
549+
});
518550
});
519551

520552
describe('put', function () {
@@ -563,5 +595,20 @@ describe('storage() -> StorageReference', function () {
563595
return Promise.resolve();
564596
}
565597
});
598+
599+
it('allows valid metadata properties for upload', async function () {
600+
const storageReference = firebase.storage().ref(`${PATH}/metadataTest.jpeg`);
601+
await storageReference.put(new jet.context.window.ArrayBuffer(), {
602+
contentType: 'image/jpg',
603+
md5hash: '123412341234',
604+
cacheControl: 'true',
605+
contentDisposition: 'disposed',
606+
contentEncoding: 'encoded',
607+
contentLanguage: 'martian',
608+
customMetadata: {
609+
customMetadata1: 'metadata1value',
610+
},
611+
});
612+
});
566613
});
567614
});

packages/storage/lib/StorageReference.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,12 @@ export default class StorageReference extends ReferenceBase {
179179
*/
180180
put(data, metadata) {
181181
if (!isUndefined(metadata)) {
182-
validateMetadata(metadata);
182+
validateMetadata(metadata, false);
183183
}
184184

185185
return new StorageUploadTask(this, task =>
186186
Base64.fromData(data).then(({ string, format }) => {
187-
const { _string, _format, _metadata } = this._updateString(string, format, metadata);
187+
const { _string, _format, _metadata } = this._updateString(string, format, metadata, false);
188188
return this._storage.native.putString(
189189
this.toString(),
190190
_string,
@@ -200,7 +200,7 @@ export default class StorageReference extends ReferenceBase {
200200
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#putString
201201
*/
202202
putString(string, format = StorageStatics.StringFormat.RAW, metadata) {
203-
const { _string, _format, _metadata } = this._updateString(string, format, metadata);
203+
const { _string, _format, _metadata } = this._updateString(string, format, metadata, false);
204204

205205
return new StorageUploadTask(this, task =>
206206
this._storage.native.putString(this.toString(), _string, _format, _metadata, task._id),
@@ -250,7 +250,7 @@ export default class StorageReference extends ReferenceBase {
250250
*/
251251
putFile(filePath, metadata) {
252252
if (!isUndefined(metadata)) {
253-
validateMetadata(metadata);
253+
validateMetadata(metadata, false);
254254
}
255255

256256
if (!isString(filePath)) {
@@ -264,7 +264,7 @@ export default class StorageReference extends ReferenceBase {
264264
);
265265
}
266266

267-
_updateString(string, format, metadata) {
267+
_updateString(string, format, metadata, update = false) {
268268
if (!isString(string)) {
269269
throw new Error(
270270
"firebase.storage.StorageReference.putString(*, _, _) 'string' expects a string value.",
@@ -280,7 +280,7 @@ export default class StorageReference extends ReferenceBase {
280280
}
281281

282282
if (!isUndefined(metadata)) {
283-
validateMetadata(metadata);
283+
validateMetadata(metadata, update);
284284
}
285285

286286
let _string = string;

packages/storage/lib/index.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ export namespace FirebaseStorageTypes {
315315
*/
316316
contentType?: string | null;
317317

318+
/**
319+
* You may specify the md5hash of the file in metadata on upload only. It may not be updated via updateMetadata
320+
*/
321+
md5hash?: string | null;
322+
318323
/**
319324
* Additional user-defined custom metadata for this storage object.
320325
*

packages/storage/lib/utils.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const SETTABLE_FIELDS = [
2525
'contentLanguage',
2626
'contentType',
2727
'customMetadata',
28+
'md5hash',
2829
];
2930

3031
export async function handleStorageEvent(storageInstance, event) {
@@ -57,7 +58,7 @@ export function getGsUrlParts(url) {
5758
return { bucket, path };
5859
}
5960

60-
export function validateMetadata(metadata) {
61+
export function validateMetadata(metadata, update = true) {
6162
if (!isObject(metadata)) {
6263
throw new Error('firebase.storage.SettableMetadata must be an object value if provided.');
6364
}
@@ -73,6 +74,13 @@ export function validateMetadata(metadata) {
7374
);
7475
}
7576

77+
// md5 is only allowed on put, not on update
78+
if (key === 'md5hash' && update === true) {
79+
throw new Error(
80+
`firebase.storage.SettableMetadata md5hash may only be set on upload, not on updateMetadata`,
81+
);
82+
}
83+
7684
// validate values
7785
if (key !== 'customMetadata') {
7886
if (!isString(value) && !isNull(value)) {

0 commit comments

Comments
 (0)