Skip to content

Commit 82a80e8

Browse files
committed
fix(storage): uploadBytes now with upstream types, tests
1 parent 3a3824b commit 82a80e8

4 files changed

Lines changed: 58 additions & 13 deletions

File tree

.github/scripts/compare-types/packages/storage/config.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,6 @@ const config: PackageConfig = {
166166
'(the Web Streams API type). The Node.js stream type is used because the ' +
167167
'React Native environment does not have the Web Streams API.',
168168
},
169-
{
170-
name: 'uploadBytes',
171-
reason:
172-
'Returns `Promise<TaskResult>` in RN Firebase instead of `Promise<UploadResult>`. ' +
173-
'`TaskResult` is a type alias for `UploadResult`, so the runtime shape is identical; ' +
174-
'the different name is for consistency with the native task system.',
175-
},
176169
{
177170
name: 'uploadBytesResumable',
178171
reason:

packages/storage/e2e/StorageTask.e2e.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,45 @@ describe('storage() -> StorageTask', function () {
10701070
});
10711071
});
10721072

1073+
describe('uploadBytes()', function () {
1074+
it('resolves with ref and metadata whose size matches uploaded bytes', async function () {
1075+
const { getStorage, ref, uploadBytes } = storageModular;
1076+
const jsonDerulo = JSON.stringify({ foo: 'bar' });
1077+
const expectedByteLength = jsonDerulo.length;
1078+
1079+
const arrayBuffer = new ArrayBuffer(jsonDerulo.length);
1080+
const arrayBufferView = new Uint8Array(arrayBuffer);
1081+
1082+
for (let i = 0, strLen = jsonDerulo.length; i < strLen; i++) {
1083+
arrayBufferView[i] = jsonDerulo.charCodeAt(i);
1084+
}
1085+
1086+
const uploadResult = await uploadBytes(
1087+
ref(getStorage(), `${PATH}/uploadBytesModular.json`),
1088+
arrayBuffer,
1089+
{
1090+
contentType: 'application/json',
1091+
},
1092+
);
1093+
1094+
uploadResult.ref.fullPath.should.containEql('uploadBytesModular.json');
1095+
uploadResult.metadata.should.be.an.Object();
1096+
uploadResult.metadata.size.should.eql(expectedByteLength);
1097+
uploadResult.metadata.contentType.should.eql('application/json');
1098+
});
1099+
1100+
it('rejects when metadata is not an object', async function () {
1101+
const { getStorage, ref, uploadBytes } = storageModular;
1102+
try {
1103+
await uploadBytes(ref(getStorage(), `${PATH}/uploadBytesBadMeta.json`), new ArrayBuffer(), 123);
1104+
return Promise.reject(new Error('Did not error!'));
1105+
} catch (error) {
1106+
error.message.should.containEql('must be an object value');
1107+
return Promise.resolve();
1108+
}
1109+
});
1110+
});
1111+
10731112
describe('upload tasks', function () {
10741113
// before(async function () {
10751114
// // TODO we need some semi-large assets to upload and download I think?

packages/storage/lib/modular.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ import type {
2424
FullMetadata,
2525
ListResult,
2626
ListOptions,
27-
TaskResult,
2827
Task,
2928
SettableMetadata,
3029
UploadMetadata,
3130
EmulatorMockTokenOptions,
31+
UploadResult,
3232
} from './types/storage';
3333
import { TaskEvent, TaskState } from './types/storage';
3434
import type { StorageReferenceInternal, StorageInternal } from './types/internal';
@@ -269,17 +269,18 @@ export function updateMetadata(
269269

270270
/**
271271
* Uploads data to this object's location. The upload is not resumable. If the upload is canceled,
272-
* the Promise will reject with the TaskSnapshot. If there is an error it will reject with the StorageError
272+
* the Promise will reject with the {TaskSnapshot}. If there is an error it will reject with the StorageError,
273+
* but as a {ReactNativeFirebase.NativeFirebaseError} type
273274
* @param storageRef - Storage `Reference` instance.
274275
* @param data - The data (Blob | Uint8Array | ArrayBuffer) to upload to the storage bucket at the reference location.
275276
* @param metadata - A Storage `UploadMetadata` instance to update. Optional.
276-
* @returns {Promise<TaskResult>}
277+
* @returns {Promise<UploadResult>}
277278
*/
278279
export async function uploadBytes(
279280
storageRef: StorageReference,
280281
data: Blob | Uint8Array | ArrayBuffer,
281282
metadata?: UploadMetadata,
282-
): Promise<TaskResult> {
283+
): Promise<UploadResult> {
283284
const task = uploadBytesResumable(storageRef, data, metadata);
284285
return new Promise((resolve, reject) => {
285286
task.on(
@@ -289,6 +290,7 @@ export async function uploadBytes(
289290
case TaskState.RUNNING:
290291
break;
291292
case TaskState.PAUSED:
293+
// we are wrapping the resumable version, just resume if it pauses
292294
task.resume();
293295
break;
294296
case TaskState.SUCCESS:
@@ -299,7 +301,7 @@ export async function uploadBytes(
299301
reject(taskSnapshot);
300302
break;
301303
case TaskState.ERROR:
302-
// this will be handled in the dedicated error listener
304+
// this is handled in the dedicated error listener below
303305
break;
304306
default:
305307
throw new Error(`Unhandled task state in uploadBytes: ${taskSnapshot.state}`);

packages/storage/type-test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import storage, {
33
// Types
44
type FirebaseStorage,
55
type FirebaseStorageTypes,
6+
type StorageReference,
67
// Modular API
78
getStorage,
89
connectStorageEmulator,
@@ -234,10 +235,20 @@ updateMetadata(modularRef1, { cacheControl: 'no-cache' }).then(
234235

235236
uploadBytes(modularRef1, new Blob(), { cacheControl: 'no-cache' }).then(
236237
(result: TaskResult) => {
237-
console.log(result);
238+
const uploadBytesRef: StorageReference = result.ref;
239+
const uploadBytesMeta: FullMetadata = result.metadata;
240+
console.log(uploadBytesRef.fullPath, uploadBytesMeta.size);
238241
},
239242
);
240243

244+
uploadBytes(modularRef1, new Uint8Array([1, 2, 3])).then((result: TaskResult) => {
245+
console.log(result.ref.name, result.metadata.size);
246+
});
247+
248+
uploadBytes(modularRef1, new ArrayBuffer(0)).then((result: TaskResult) => {
249+
console.log(result.metadata.fullPath);
250+
});
251+
241252
const modularUploadBytesResumable = uploadBytesResumable(modularRef1, new Blob(), {
242253
cacheControl: 'no-cache',
243254
});

0 commit comments

Comments
 (0)