Skip to content

Commit 4dd2790

Browse files
WIP: getBytes
1 parent 61b69aa commit 4dd2790

File tree

6 files changed

+76
-5
lines changed

6 files changed

+76
-5
lines changed

packages/storage/compat/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function factory(
5050

5151
const storageServiceCompat: StorageServiceCompat = new StorageServiceCompat(
5252
app,
53-
storageExp
53+
storageExp as any
5454
);
5555
return storageServiceCompat;
5656
}

packages/storage/exp/api.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ import {
5151
getDownloadURL as getDownloadURLInternal,
5252
deleteObject as deleteObjectInternal,
5353
Reference,
54-
_getChild as _getChildInternal
54+
_getChild as _getChildInternal,
55+
getBytesInternal
5556
} from '../src/reference';
5657
import { STORAGE_TYPE } from './constants';
5758
import { getModularInstance } from '@firebase/util';
@@ -66,6 +67,19 @@ export { UploadTask as _UploadTask } from '../src/task';
6667
export type { Reference as _Reference } from '../src/reference';
6768
export { FbsBlob as _FbsBlob } from '../src/implementation/blob';
6869

70+
/**
71+
* Download's the data at the object's location. Returns an error if the object
72+
* is not found.
73+
*
74+
* @public
75+
* @param ref - StorageReference where data should be download.
76+
* @returns A Promise containing an UploadResult
77+
*/
78+
export function getBytes(ref: StorageReference): Promise<Uint8Array> {
79+
ref = getModularInstance(ref);
80+
return getBytesInternal(ref as Reference);
81+
}
82+
6983
/**
7084
* Uploads data to this object's location.
7185
* The upload is not resumable.

packages/storage/src/implementation/requests.ts

+29
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,35 @@ export function list(
206206
return requestInfo;
207207
}
208208

209+
export function getBytes(
210+
service: StorageService,
211+
location: Location,
212+
mappings: Mappings
213+
): RequestInfo<Uint8Array> {
214+
const urlPart = location.fullServerUrl();
215+
const url = makeUrl(urlPart, service.host) + '?alt=media';
216+
const method = 'GET';
217+
const timeout = service.maxOperationRetryTime;
218+
const requestInfo = new RequestInfo(
219+
url,
220+
method,
221+
getBytesHandler(service, mappings),
222+
timeout
223+
);
224+
requestInfo.errorHandler = objectErrorHandler(location);
225+
return requestInfo;
226+
}
227+
228+
export function getBytesHandler(
229+
service: StorageService,
230+
mappings: Mappings
231+
): (p1: XhrIo, p2: string) => Uint8Array {
232+
function handler(xhr: XhrIo, data: string): Uint8Array {
233+
return (data as any) as Uint8Array;
234+
}
235+
return handler;
236+
}
237+
209238
export function getDownloadUrl(
210239
service: StorageService,
211240
location: Location,

packages/storage/src/reference.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import {
2929
updateMetadata as requestsUpdateMetadata,
3030
getDownloadUrl as requestsGetDownloadUrl,
3131
deleteObject as requestsDeleteObject,
32-
multipartUpload
32+
multipartUpload,
33+
getBytes
3334
} from './implementation/requests';
3435
import { ListOptions } from '../exp/public-types';
3536
import { StringFormat, dataFromString } from './implementation/string';
@@ -137,6 +138,19 @@ export class Reference {
137138
}
138139
}
139140

141+
/**
142+
* Download the bytes at the object's location.
143+
144+
* @returns A Promise containing the downloaded bytes.
145+
*/
146+
export function getBytesInternal(ref: Reference): Promise<Uint8Array> {
147+
ref._throwIfRoot('getBytes');
148+
const requestInfo = getBytes(ref.storage, ref._location, getMappings());
149+
return ref.storage
150+
.makeRequestWithTokens(requestInfo)
151+
.then(request => request.getPromise());
152+
}
153+
140154
/**
141155
* Uploads data to this object's location.
142156
* The upload is not resumable.

packages/storage/test/integration/integration.exp.test.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import {
2929
deleteObject,
3030
getMetadata,
3131
updateMetadata,
32-
listAll
32+
listAll,
33+
getBytes
3334
} from '../../exp/index';
3435

3536
import { use, expect } from 'chai';
@@ -71,6 +72,19 @@ describe('FirebaseStorage Exp', () => {
7172
expect(snap.metadata.timeCreated).to.exist;
7273
});
7374

75+
it.only('can get bytes', async () => {
76+
const reference = ref(storage, 'public/exp-bytes');
77+
await uploadBytes(reference, new Uint8Array([0, 1, 3]));
78+
const bytes = await getBytes(reference);
79+
expect(bytes).to.deep.equal(new Uint8Array([0, 1, 3]));
80+
});
81+
82+
it.only('getBytes() throws for missing file', async () => {
83+
const reference = ref(storage, 'public/exp-bytes-missing');
84+
const bytes = await getBytes(reference);
85+
expect(bytes).to.deep.equal(new Uint8Array([0, 1, 3]));
86+
});
87+
7488
it('can upload bytes (resumable)', async () => {
7589
const reference = ref(storage, 'public/exp-bytesresumable');
7690
const snap = await uploadBytesResumable(

packages/storage/test/unit/reference.compat.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ describe('Firebase Storage > Reference', () => {
7575
expect(s.toString()).to.equal('gs://test-bucket/this/ismyobject?hello');
7676
});
7777
it("doesn't URL-decode on a gs:// string", () => {
78-
const s = makeStorage('gs://test-bucket/%3F');
78+
const s = makeStorage('gs://testbucket/%3F');
7979
expect(s.toString()).to.equal('gs://test-bucket/%3F');
8080
});
8181
it('ignores URL params and fragments on an http URL', () => {

0 commit comments

Comments
 (0)