Skip to content

Commit fb55c6c

Browse files
committed
Migrate storage to component framework (#2326)
1 parent f0c5859 commit fb55c6c

File tree

9 files changed

+148
-47
lines changed

9 files changed

+148
-47
lines changed

packages/storage/index.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,36 @@
1616
*/
1717

1818
import firebase from '@firebase/app';
19-
import { FirebaseApp } from '@firebase/app-types';
20-
import {
21-
FirebaseServiceFactory,
22-
_FirebaseNamespace
23-
} from '@firebase/app-types/private';
19+
import { _FirebaseNamespace } from '@firebase/app-types/private';
2420
import { StringFormat } from './src/implementation/string';
2521
import { TaskEvent, TaskState } from './src/implementation/taskenums';
2622

2723
import { XhrIoPool } from './src/implementation/xhriopool';
2824
import { Reference } from './src/reference';
2925
import { Service } from './src/service';
3026
import * as types from '@firebase/storage-types';
27+
import {
28+
Component,
29+
ComponentType,
30+
ComponentContainer
31+
} from '@firebase/component';
3132

3233
/**
3334
* Type constant for Firebase Storage.
3435
*/
3536
const STORAGE_TYPE = 'storage';
3637

3738
function factory(
38-
app: FirebaseApp,
39-
unused: unknown,
39+
container: ComponentContainer,
4040
url?: string
4141
): types.FirebaseStorage {
42+
// Dependencies
43+
const app = container.getProvider('app').getImmediate();
44+
const authProvider = container.getProvider('auth-internal');
45+
4246
return (new Service(
4347
app,
48+
authProvider,
4449
new XhrIoPool(),
4550
url
4651
) as unknown) as types.FirebaseStorage;
@@ -55,13 +60,10 @@ export function registerStorage(instance: _FirebaseNamespace): void {
5560
Storage: Service,
5661
Reference
5762
};
58-
instance.INTERNAL.registerService(
59-
STORAGE_TYPE,
60-
factory as FirebaseServiceFactory,
61-
namespaceExports,
62-
undefined,
63-
// Allow multiple storage instances per app.
64-
true
63+
instance.INTERNAL.registerComponent(
64+
new Component(STORAGE_TYPE, factory, ComponentType.PUBLIC)
65+
.setServiceProps(namespaceExports)
66+
.setMultipleInstances(true)
6567
);
6668
}
6769

packages/storage/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"dependencies": {
2323
"@firebase/storage-types": "0.3.5",
2424
"@firebase/util": "0.2.31",
25+
"@firebase/component": "0.1.0",
2526
"tslib": "1.10.0"
2627
},
2728
"peerDependencies": {

packages/storage/src/implementation/authwrapper.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import {
3131
_FirebaseApp,
3232
FirebaseAuthTokenData
3333
} from '@firebase/app-types/private';
34+
import { Provider } from '@firebase/component';
35+
import { FirebaseAuthInternal } from '@firebase/auth-interop-types';
3436

3537
/**
3638
* @param app If null, getAuthToken always resolves with null.
@@ -40,6 +42,7 @@ import {
4042
*/
4143
export class AuthWrapper {
4244
private app_: FirebaseApp | null;
45+
private authProvider_: Provider<FirebaseAuthInternal>;
4346
private bucket_: string | null = null;
4447

4548
private storageRefMaker_: (p1: AuthWrapper, p2: Location) => Reference;
@@ -53,6 +56,7 @@ export class AuthWrapper {
5356

5457
constructor(
5558
app: FirebaseApp | null,
59+
authProvider: Provider<FirebaseAuthInternal>,
5660
maker: (p1: AuthWrapper, p2: Location) => Reference,
5761
requestMaker: requestMaker,
5862
service: Service,
@@ -65,6 +69,7 @@ export class AuthWrapper {
6569
this.bucket_ = AuthWrapper.extractBucket_(options);
6670
}
6771
}
72+
this.authProvider_ = authProvider;
6873
this.storageRefMaker_ = maker;
6974
this.requestMaker_ = requestMaker;
7075
this.pool_ = pool;
@@ -84,14 +89,9 @@ export class AuthWrapper {
8489
}
8590

8691
getAuthToken(): Promise<string | null> {
87-
// TODO(andysoto): remove ifDef checks after firebase-app implements stubs
88-
// (b/28673818).
89-
if (
90-
this.app_ !== null &&
91-
type.isDef((this.app_ as _FirebaseApp).INTERNAL) &&
92-
type.isDef((this.app_ as _FirebaseApp).INTERNAL.getToken)
93-
) {
94-
return (this.app_ as _FirebaseApp).INTERNAL.getToken().then(
92+
const auth = this.authProvider_.getImmediate(undefined, { optional: true });
93+
if (auth) {
94+
return auth.getToken().then(
9595
(response: FirebaseAuthTokenData | null): string | null => {
9696
if (response !== null) {
9797
return response.accessToken;

packages/storage/src/service.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import { Location } from './implementation/location';
2222
import * as RequestExports from './implementation/request';
2323
import { XhrIoPool } from './implementation/xhriopool';
2424
import { Reference } from './reference';
25+
import { Provider } from '@firebase/component';
26+
import { FirebaseAuthInternal } from '@firebase/auth-interop-types';
2527

2628
/**
2729
* A service that provides firebaseStorage.Reference instances.
@@ -35,12 +37,18 @@ export class Service {
3537
private bucket_: Location | null = null;
3638
private internals_: ServiceInternals;
3739

38-
constructor(app: FirebaseApp, pool: XhrIoPool, url?: string) {
40+
constructor(
41+
app: FirebaseApp,
42+
authProvider: Provider<FirebaseAuthInternal>,
43+
pool: XhrIoPool,
44+
url?: string
45+
) {
3946
function maker(authWrapper: AuthWrapper, loc: Location): Reference {
4047
return new Reference(authWrapper, loc);
4148
}
4249
this.authWrapper_ = new AuthWrapper(
4350
app,
51+
authProvider,
4452
maker,
4553
RequestExports.makeRequest,
4654
this,

packages/storage/test/reference.test.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,16 @@ import { Service } from '../src/service';
2626
import * as testShared from './testshared';
2727
import { SendHook, TestingXhrIo } from './xhrio';
2828
import { DEFAULT_HOST } from '../src/implementation/constants';
29+
import { FirebaseAuthInternal } from '@firebase/auth-interop-types';
30+
import { Provider } from '@firebase/component';
31+
2932
/* eslint-disable @typescript-eslint/no-floating-promises */
30-
function makeFakeService(app: FirebaseApp, sendHook: SendHook): Service {
31-
return new Service(app, testShared.makePool(sendHook));
33+
function makeFakeService(
34+
app: FirebaseApp,
35+
authProvider: Provider<FirebaseAuthInternal>,
36+
sendHook: SendHook
37+
): Service {
38+
return new Service(app, authProvider, testShared.makePool(sendHook));
3239
}
3340

3441
function makeStorage(url: string): Reference {
@@ -38,6 +45,7 @@ function makeStorage(url: string): Reference {
3845

3946
const authWrapper = new AuthWrapper(
4047
null,
48+
testShared.emptyAuthProvider,
4149
maker,
4250
makeRequest,
4351
({} as any) as Service,
@@ -190,7 +198,11 @@ describe('Firebase Storage > Reference', () => {
190198
done();
191199
}
192200

193-
const service = makeFakeService(testShared.fakeAppNoAuth, newSend);
201+
const service = makeFakeService(
202+
testShared.fakeApp,
203+
testShared.emptyAuthProvider,
204+
newSend
205+
);
194206
const ref = service.refFromURL('gs://test-bucket');
195207
ref.child('foo').getMetadata();
196208
});
@@ -212,7 +224,11 @@ describe('Firebase Storage > Reference', () => {
212224
done();
213225
}
214226

215-
const service = makeFakeService(testShared.fakeApp, newSend);
227+
const service = makeFakeService(
228+
testShared.fakeApp,
229+
testShared.fakeAuthProvider,
230+
newSend
231+
);
216232
const ref = service.refFromURL('gs://test-bucket');
217233
ref.child('foo').getMetadata();
218234
});

packages/storage/test/requests.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ import { XhrIoPool } from '../src/implementation/xhriopool';
2828
import { Metadata } from '../src/metadata';
2929
import { Reference } from '../src/reference';
3030
import { Service } from '../src/service';
31-
import { assertObjectIncludes, fakeXhrIo } from './testshared';
31+
import {
32+
assertObjectIncludes,
33+
fakeXhrIo,
34+
fakeAuthProvider
35+
} from './testshared';
3236
import {
3337
DEFAULT_HOST,
3438
CONFIG_STORAGE_BUCKET_KEY
@@ -61,6 +65,7 @@ describe('Firebase Storage > Requests', () => {
6165

6266
const authWrapper = new AuthWrapper(
6367
mockApp,
68+
fakeAuthProvider,
6469
(authWrapper, loc) => {
6570
return new Reference(authWrapper, loc);
6671
},

packages/storage/test/service.test.ts

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ import * as testShared from './testshared';
2222
import { DEFAULT_HOST } from '../src/implementation/constants';
2323
import { FirebaseStorageError } from '../src/implementation/error';
2424

25-
const fakeAppGs = testShared.makeFakeApp(null, 'gs://mybucket');
26-
const fakeAppGsEndingSlash = testShared.makeFakeApp(null, 'gs://mybucket/');
27-
const fakeAppInvalidGs = testShared.makeFakeApp(null, 'gs://mybucket/hello');
25+
const fakeAppGs = testShared.makeFakeApp('gs://mybucket');
26+
const fakeAppGsEndingSlash = testShared.makeFakeApp('gs://mybucket/');
27+
const fakeAppInvalidGs = testShared.makeFakeApp('gs://mybucket/hello');
2828
const xhrIoPool = new XhrIoPool();
2929

3030
function makeGsUrl(child: string = ''): string {
@@ -33,7 +33,11 @@ function makeGsUrl(child: string = ''): string {
3333

3434
describe('Firebase Storage > Service', () => {
3535
describe('simple constructor', () => {
36-
const service = new Service(testShared.fakeApp, xhrIoPool);
36+
const service = new Service(
37+
testShared.fakeApp,
38+
testShared.fakeAuthProvider,
39+
xhrIoPool
40+
);
3741
it('Root refs point to the right place', () => {
3842
const ref = service.ref();
3943
assert.equal(ref.toString(), makeGsUrl());
@@ -65,6 +69,7 @@ describe('Firebase Storage > Service', () => {
6569
it('gs:// custom bucket constructor refs point to the right place', () => {
6670
const service = new Service(
6771
testShared.fakeApp,
72+
testShared.fakeAuthProvider,
6873
xhrIoPool,
6974
'gs://foo-bar.appspot.com'
7075
);
@@ -74,6 +79,7 @@ describe('Firebase Storage > Service', () => {
7479
it('http:// custom bucket constructor refs point to the right place', () => {
7580
const service = new Service(
7681
testShared.fakeApp,
82+
testShared.fakeAuthProvider,
7783
xhrIoPool,
7884
`http://${DEFAULT_HOST}/v1/b/foo-bar.appspot.com/o`
7985
);
@@ -83,6 +89,7 @@ describe('Firebase Storage > Service', () => {
8389
it('https:// custom bucket constructor refs point to the right place', () => {
8490
const service = new Service(
8591
testShared.fakeApp,
92+
testShared.fakeAuthProvider,
8693
xhrIoPool,
8794
`https://${DEFAULT_HOST}/v1/b/foo-bar.appspot.com/o`
8895
);
@@ -93,6 +100,7 @@ describe('Firebase Storage > Service', () => {
93100
it('Bare bucket name constructor refs point to the right place', () => {
94101
const service = new Service(
95102
testShared.fakeApp,
103+
testShared.fakeAuthProvider,
96104
xhrIoPool,
97105
'foo-bar.appspot.com'
98106
);
@@ -102,6 +110,7 @@ describe('Firebase Storage > Service', () => {
102110
it('Child refs point to the right place', () => {
103111
const service = new Service(
104112
testShared.fakeApp,
113+
testShared.fakeAuthProvider,
105114
xhrIoPool,
106115
'foo-bar.appspot.com'
107116
);
@@ -110,28 +119,45 @@ describe('Firebase Storage > Service', () => {
110119
});
111120
it('Throws trying to construct with a gs:// URL containing an object path', () => {
112121
const error = testShared.assertThrows(() => {
113-
new Service(testShared.fakeApp, xhrIoPool, 'gs://bucket/object/');
122+
new Service(
123+
testShared.fakeApp,
124+
testShared.fakeAuthProvider,
125+
xhrIoPool,
126+
'gs://bucket/object/'
127+
);
114128
}, 'storage/invalid-default-bucket');
115129
assert.match(error.message, /Invalid default bucket/);
116130
});
117131
});
118132
describe('default bucket config', () => {
119133
it('gs:// works without ending slash', () => {
120-
const service = new Service(fakeAppGs, xhrIoPool);
134+
const service = new Service(
135+
fakeAppGs,
136+
testShared.fakeAuthProvider,
137+
xhrIoPool
138+
);
121139
assert.equal(service.ref().toString(), 'gs://mybucket/');
122140
});
123141
it('gs:// works with ending slash', () => {
124-
const service = new Service(fakeAppGsEndingSlash, xhrIoPool);
142+
const service = new Service(
143+
fakeAppGsEndingSlash,
144+
testShared.fakeAuthProvider,
145+
xhrIoPool
146+
);
125147
assert.equal(service.ref().toString(), 'gs://mybucket/');
126148
});
127149
it('Throws when config bucket is gs:// with an object path', () => {
128150
testShared.assertThrows(() => {
129-
new Service(fakeAppInvalidGs, xhrIoPool);
151+
new Service(fakeAppInvalidGs, testShared.fakeAuthProvider, xhrIoPool);
130152
}, 'storage/invalid-default-bucket');
131153
});
132154
});
133155
describe('refFromURL', () => {
134-
const service = new Service(testShared.fakeApp, xhrIoPool);
156+
const service = new Service(
157+
testShared.fakeApp,
158+
testShared.fakeAuthProvider,
159+
xhrIoPool
160+
);
135161
it('Throws on non-URL arg', () => {
136162
const error = testShared.assertThrows(() => {
137163
service.refFromURL('path/to/child');
@@ -158,7 +184,11 @@ describe('Firebase Storage > Service', () => {
158184
});
159185
});
160186
describe('Argument verification', () => {
161-
const service = new Service(testShared.fakeApp, xhrIoPool);
187+
const service = new Service(
188+
testShared.fakeApp,
189+
testShared.fakeAuthProvider,
190+
xhrIoPool
191+
);
162192
describe('ref', () => {
163193
it('Throws with two args', () => {
164194
testShared.assertThrows(
@@ -272,7 +302,11 @@ describe('Firebase Storage > Service', () => {
272302
});
273303

274304
describe('Deletion', () => {
275-
const service = new Service(testShared.fakeApp, xhrIoPool);
305+
const service = new Service(
306+
testShared.fakeApp,
307+
testShared.fakeAuthProvider,
308+
xhrIoPool
309+
);
276310
it('In-flight requests are canceled when the service is deleted', () => {
277311
const ref = service.refFromURL('gs://mybucket/image.jpg');
278312
const toReturn = ref.getMetadata().then(

packages/storage/test/task.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ import { Headers } from '../src/implementation/xhrio';
2626
import { Reference } from '../src/reference';
2727
import { Service } from '../src/service';
2828
import { UploadTask } from '../src/task';
29-
import { assertThrows, bind as fbsBind, makePool } from './testshared';
29+
import {
30+
assertThrows,
31+
bind as fbsBind,
32+
makePool,
33+
emptyAuthProvider
34+
} from './testshared';
3035
import { StringHeaders, TestingXhrIo } from './xhrio';
3136

3237
const testLocation = new Location('bucket', 'object');
@@ -63,6 +68,7 @@ function authWrapperWithHandler(handler: RequestHandler): AuthWrapper {
6368

6469
return new AuthWrapper(
6570
null,
71+
emptyAuthProvider,
6672
() => {
6773
return {} as Reference;
6874
},

0 commit comments

Comments
 (0)