Skip to content

Commit 5afb588

Browse files
committed
issue firebase#2393, first fix on performance module and remote-config module
1 parent 9b32270 commit 5afb588

File tree

5 files changed

+117
-10
lines changed

5 files changed

+117
-10
lines changed

packages/firebase/index.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1602,6 +1602,7 @@ declare namespace firebase.performance {
16021602
*/
16031603
getAttributes(): { [key: string]: string };
16041604
}
1605+
function isSupported(): boolean;
16051606
}
16061607

16071608
/**
@@ -1771,6 +1772,8 @@ declare namespace firebase.remoteConfig {
17711772
* Defines levels of Remote Config logging.
17721773
*/
17731774
export type LogLevel = 'debug' | 'error' | 'silent';
1775+
1776+
function isSupported(): boolean;
17741777
}
17751778

17761779
declare namespace firebase.functions {

packages/performance/index.ts

+51-1
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,20 @@ export function registerPerformance(instance: FirebaseNamespace): void {
4242
if (typeof window === 'undefined') {
4343
throw ERROR_FACTORY.create(ErrorCode.NO_WINDOW);
4444
}
45+
if (!isSupported()) {
46+
throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);
47+
}
48+
4549
setupApi(window);
4650
SettingsService.getInstance().firebaseAppInstance = app;
4751
SettingsService.getInstance().installationsService = installations;
4852
return new PerformanceController(app);
4953
};
5054

55+
const NAMESPACE_EXPORTS = {
56+
isSupported
57+
};
58+
5159
// Register performance with firebase-app.
5260
(instance as _FirebaseNamespace).INTERNAL.registerComponent(
5361
new Component(
@@ -64,7 +72,7 @@ export function registerPerformance(instance: FirebaseNamespace): void {
6472
return factoryMethod(app, installations);
6573
},
6674
ComponentType.PUBLIC
67-
)
75+
).setServiceProps(NAMESPACE_EXPORTS)
6876
);
6977

7078
instance.registerVersion(name, version);
@@ -76,9 +84,51 @@ declare module '@firebase/app-types' {
7684
interface FirebaseNamespace {
7785
performance?: {
7886
(app?: FirebaseApp): FirebasePerformance;
87+
isSupprted(): boolean;
7988
};
8089
}
8190
interface FirebaseApp {
8291
performance?(): FirebasePerformance;
8392
}
8493
}
94+
95+
function isSupported(): boolean {
96+
if (self && 'ServiceWorkerGlobalScope' in self) {
97+
// Running in ServiceWorker context
98+
return isSWControllerSupported();
99+
} else {
100+
// Assume we are in the window context.
101+
return isWindowControllerSupported();
102+
}
103+
}
104+
105+
/**
106+
* Checks to see if the required APIs exist.
107+
*/
108+
function isWindowControllerSupported(): boolean {
109+
return (
110+
'indexedDB' in window &&
111+
indexedDB !== null &&
112+
navigator.cookieEnabled &&
113+
'serviceWorker' in navigator &&
114+
'PushManager' in window &&
115+
'Notification' in window &&
116+
'fetch' in window &&
117+
ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&
118+
PushSubscription.prototype.hasOwnProperty('getKey')
119+
);
120+
}
121+
122+
/**
123+
* Checks to see if the required APIs exist within SW Context.
124+
*/
125+
function isSWControllerSupported(): boolean {
126+
return (
127+
'indexedDB' in self &&
128+
indexedDB !== null &&
129+
'PushManager' in self &&
130+
'Notification' in self &&
131+
ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&
132+
PushSubscription.prototype.hasOwnProperty('getKey')
133+
);
134+
}

packages/performance/src/utils/errors.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export const enum ErrorCode {
3131
INVALID_ATTRIBUTE_NAME = 'invalid attribute name',
3232
INVALID_ATTRIBUTE_VALUE = 'invalid attribute value',
3333
INVALID_CUSTOM_METRIC_NAME = 'invalid custom metric name',
34-
INVALID_STRING_MERGER_PARAMETER = 'invalid String merger input'
34+
INVALID_STRING_MERGER_PARAMETER = 'invalid String merger input',
35+
UNSUPPORTED_BROWSER = 'unsupported-browser'
3536
}
3637

3738
const ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {
@@ -52,7 +53,9 @@ const ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {
5253
[ErrorCode.INVALID_CUSTOM_METRIC_NAME]:
5354
'Custom metric name {$customMetricName} is invalid',
5455
[ErrorCode.INVALID_STRING_MERGER_PARAMETER]:
55-
'Input for String merger is invalid, contact support team to resolve.'
56+
'Input for String merger is invalid, contact support team to resolve.',
57+
[ErrorCode.UNSUPPORTED_BROWSER]:
58+
"This browser doesn't support the API's required to use the firebase SDK."
5659
};
5760

5861
interface ErrorParams {

packages/remote-config/index.ts

+53-5
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,17 @@ declare global {
4444
}
4545
}
4646

47+
const NAMESPACE_EXPORTS = {
48+
isSupported
49+
};
50+
4751
export function registerRemoteConfig(
4852
firebaseInstance: _FirebaseNamespace
4953
): void {
5054
firebaseInstance.INTERNAL.registerComponent(
51-
new Component(
52-
'remoteConfig',
53-
remoteConfigFactory,
54-
ComponentType.PUBLIC
55-
).setMultipleInstances(true)
55+
new Component('remoteConfig', remoteConfigFactory, ComponentType.PUBLIC)
56+
.setMultipleInstances(true)
57+
.setServiceProps(NAMESPACE_EXPORTS)
5658
);
5759

5860
firebaseInstance.registerVersion(packageName, version);
@@ -72,6 +74,10 @@ export function registerRemoteConfig(
7274
throw ERROR_FACTORY.create(ErrorCode.REGISTRATION_WINDOW);
7375
}
7476

77+
if (!isSupported()) {
78+
throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);
79+
}
80+
7581
// Normalizes optional inputs.
7682
const { projectId, apiKey, appId } = app.options;
7783
if (!projectId) {
@@ -133,9 +139,51 @@ declare module '@firebase/app-types' {
133139
interface FirebaseNamespace {
134140
remoteConfig?: {
135141
(app?: FirebaseApp): RemoteConfigType;
142+
isSupported(): boolean;
136143
};
137144
}
138145
interface FirebaseApp {
139146
remoteConfig(): RemoteConfigType;
140147
}
141148
}
149+
150+
function isSupported(): boolean {
151+
if (self && 'ServiceWorkerGlobalScope' in self) {
152+
// Running in ServiceWorker context
153+
return isSWControllerSupported();
154+
} else {
155+
// Assume we are in the window context.
156+
return isWindowControllerSupported();
157+
}
158+
}
159+
160+
/**
161+
* Checks to see if the required APIs exist.
162+
*/
163+
function isWindowControllerSupported(): boolean {
164+
return (
165+
'indexedDB' in window &&
166+
indexedDB !== null &&
167+
navigator.cookieEnabled &&
168+
'serviceWorker' in navigator &&
169+
'PushManager' in window &&
170+
'Notification' in window &&
171+
'fetch' in window &&
172+
ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&
173+
PushSubscription.prototype.hasOwnProperty('getKey')
174+
);
175+
}
176+
177+
/**
178+
* Checks to see if the required APIs exist within SW Context.
179+
*/
180+
function isSWControllerSupported(): boolean {
181+
return (
182+
'indexedDB' in self &&
183+
indexedDB !== null &&
184+
'PushManager' in self &&
185+
'Notification' in self &&
186+
ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&
187+
PushSubscription.prototype.hasOwnProperty('getKey')
188+
);
189+
}

packages/remote-config/src/errors.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ export const enum ErrorCode {
3030
FETCH_TIMEOUT = 'fetch-timeout',
3131
FETCH_THROTTLE = 'fetch-throttle',
3232
FETCH_PARSE = 'fetch-client-parse',
33-
FETCH_STATUS = 'fetch-status'
33+
FETCH_STATUS = 'fetch-status',
34+
UNSUPPORTED_BROWSER = 'unsupported-browser'
3435
}
3536

3637
const ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {
@@ -64,7 +65,9 @@ const ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {
6465
'Fetch client could not parse response.' +
6566
' Original error: {$originalErrorMessage}.',
6667
[ErrorCode.FETCH_STATUS]:
67-
'Fetch server returned an HTTP error status. HTTP status: {$httpStatus}.'
68+
'Fetch server returned an HTTP error status. HTTP status: {$httpStatus}.',
69+
[ErrorCode.UNSUPPORTED_BROWSER]:
70+
"This browser doesn't support the API's required to use the firebase SDK."
6871
};
6972

7073
// Note this is effectively a type system binding a code to params. This approach overlaps with the

0 commit comments

Comments
 (0)