Skip to content

Issue 2393 - Add environment check to Analytics Module #3165

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
Jul 16, 2020
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
0843a6e
updateDoc()/deleteDoc() signature fix (#3147)
schmidt-sebastian Jun 2, 2020
0c426c3
Transaction/WriteBatch signature fix (#3151)
schmidt-sebastian Jun 2, 2020
fd0c0a3
Take WriteStream offline when IndexedDB is unavailable (#2995)
schmidt-sebastian Jun 2, 2020
9512b48
Do not build firestore lite in build because it breaks regular releas…
Feiyang1 Jun 3, 2020
b5c7b78
add pre script for build:release (#3161)
Feiyang1 Jun 3, 2020
e10388c
Add setLogLevel() (#3154)
schmidt-sebastian Jun 3, 2020
3ac0fe3
Add DocumentReference (#3123)
schmidt-sebastian Jun 3, 2020
a377c68
issue #2393 fix for analytics module
XuechunHou Jun 4, 2020
5932e87
removed unnecessary sw check within isSupported method for analytics
XuechunHou Jun 4, 2020
541bb0c
resolved merge conflicts
XuechunHou Jun 5, 2020
0090a18
using raw indexDB api to open a dummy database
XuechunHou Jun 8, 2020
8e979a3
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jun 8, 2020
7d419f1
added console log for reading code
XuechunHou Jun 9, 2020
08e4a6f
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jun 17, 2020
571e514
fix for issue-2393
XuechunHou Jun 17, 2020
b22c1fc
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jun 17, 2020
dc75ec1
removed unused import
XuechunHou Jun 17, 2020
64d8be7
fixed so that correct type of variable of errorInfo required errorFa…
XuechunHou Jun 17, 2020
099816a
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jun 23, 2020
c8cc946
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jun 24, 2020
d16cbbd
fixed isSupported export
XuechunHou Jun 24, 2020
ad09146
addressed feedback
XuechunHou Jun 24, 2020
948a5da
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jun 24, 2020
a1103e1
removed unnecessary console log
XuechunHou Jun 24, 2020
f341f94
removed console logs
XuechunHou Jun 24, 2020
111d792
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jun 30, 2020
c9f137b
addressed feedback
XuechunHou Jun 30, 2020
1fa549c
revert unrelated files
XuechunHou Jun 30, 2020
9d12700
Create clean-numbers-flow.md
XuechunHou Jun 30, 2020
2b00fc1
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jul 2, 2020
c5e2596
Merge branch 'issue-2393-analytics' of https://github.com/firebase/fi…
XuechunHou Jul 2, 2020
e30d0ec
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jul 6, 2020
d7b3359
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jul 7, 2020
12852f9
bring functions to util
XuechunHou Jul 7, 2020
e9eb751
convert validateIndexedDBOpenable to async
XuechunHou Jul 7, 2020
e00edfa
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jul 8, 2020
68387e6
trying to fix async error throwing
XuechunHou Jul 8, 2020
17973b6
brought indexedDB check to factory method
XuechunHou Jul 9, 2020
44e5aeb
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jul 9, 2020
1321327
fixed grammar error
XuechunHou Jul 10, 2020
6debf5d
break down functions
XuechunHou Jul 13, 2020
21a4f7c
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jul 13, 2020
db750f8
take indexedDB check funcitons out to factory method
XuechunHou Jul 13, 2020
4dec8d9
changed error names
XuechunHou Jul 13, 2020
9d46212
removed eslint comment
XuechunHou Jul 14, 2020
51303b0
Merge branch 'master' of https://github.com/firebase/firebase-js-sdk …
XuechunHou Jul 14, 2020
64df7e5
revert license change
XuechunHou Jul 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion packages/analytics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ declare global {
* Type constant for Firebase Analytics.
*/
const ANALYTICS_TYPE = 'analytics';
const NAMESPACE_EXPORTS = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is copied from messaging, but I don't think it's necessary here. In messaging, this was the top-level object passed to setServiceProps(). Here, the top level object is a literal that currently contains settings and EventName, so you're adding another key named NAMESPACE_EXPORTS which contains this nested object that contains isSupported(). Have you manually tested calling the isSupported() static method? Did this work?

isSupported
};
export function registerAnalytics(instance: _FirebaseNamespace): void {
instance.INTERNAL.registerComponent(
new Component(
Expand All @@ -56,12 +59,15 @@ export function registerAnalytics(instance: _FirebaseNamespace): void {
.getProvider('installations')
.getImmediate();

validateBrowserContext();

return factory(app, installations);
},
ComponentType.PUBLIC
).setServiceProps({
settings,
EventName
EventName,
NAMESPACE_EXPORTS
})
);

Expand Down Expand Up @@ -97,8 +103,52 @@ registerAnalytics(firebase as _FirebaseNamespace);
declare module '@firebase/app-types' {
interface FirebaseNamespace {
analytics(app?: FirebaseApp): FirebaseAnalytics;
isSupported(): boolean;
}
interface FirebaseApp {
analytics(): FirebaseAnalytics;
}
}
function validateBrowserContext(): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably add jsdoc style comment explaining what this function does.

if ('indexedDB' in window && indexedDB !== null && navigator.cookieEnabled) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the cookieEnabled a separate condition? I don't want to give a misleading error that indexedDB isn't available if it is available, but cookies are not.

try {
let preExist: boolean = true;
const DUMMYDBNAME =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe DB_CHECK_NAME

'a-dummy-database-for-testing-browser-context-firebase';
const request = window.indexedDB.open(DUMMYDBNAME);
request.onsuccess = () => {
//console.log('successfully opend dummy indexedDB');
request.result.close();
// delete database only when it doesn't pre-exist
if (!preExist) {
//console.log("deleting database");
window.indexedDB.deleteDatabase(DUMMYDBNAME);
}
};
request.onupgradeneeded = () => {
preExist = false;
//console.log('database needs to be upgraded');
};

request.onerror = () => {
throw ERROR_FACTORY.create(AnalyticsError.INVALID_INDEXED_DB_CONTEXT, {
errorInfo: request.error!.message
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any possibility there might not be an error or a message? would it be safer to go with request.error?.message || '' just in case?

});
};
} catch (error) {
throw ERROR_FACTORY.create(AnalyticsError.INVALID_INDEXED_DB_CONTEXT, {
errorInfo: error
});
}
} else {
throw ERROR_FACTORY.create(AnalyticsError.INDEXED_DB_UNSUPPORTED);
}
}
function isSupported(): boolean {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably have jsdoc style comment explaining what this function does.

try {
validateBrowserContext();
return true;
} catch (e) {
return false;
}
}
11 changes: 9 additions & 2 deletions packages/analytics/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export const enum AnalyticsError {
NO_GA_ID = 'no-ga-id',
ALREADY_EXISTS = 'already-exists',
ALREADY_INITIALIZED = 'already-initialized',
INTEROP_COMPONENT_REG_FAILED = 'interop-component-reg-failed'
INTEROP_COMPONENT_REG_FAILED = 'interop-component-reg-failed',
INDEXED_DB_UNSUPPORTED = 'indexedDB-unsupported',
INVALID_INDEXED_DB_CONTEXT = 'invalid-indexedDB-context'
}

const ERRORS: ErrorMap<AnalyticsError> = {
Expand All @@ -39,12 +41,17 @@ const ERRORS: ErrorMap<AnalyticsError> = {
'settings() must be called before initializing any Analytics instance' +
'or it will have no effect.',
[AnalyticsError.INTEROP_COMPONENT_REG_FAILED]:
'Firebase Analytics Interop Component failed to instantiate'
'Firebase Analytics Interop Component failed to instantiate',
[AnalyticsError.INDEXED_DB_UNSUPPORTED]:
'IndexedDB is not supported by current browswer',
[AnalyticsError.INVALID_INDEXED_DB_CONTEXT]:
"Environment doesn't support IndexedDB functionality with error message: {$errorInfo}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think we need the words with error message, just ...functionality: {$errorInfo}

};

interface ErrorParams {
[AnalyticsError.ALREADY_EXISTS]: { id: string };
[AnalyticsError.INTEROP_COMPONENT_REG_FAILED]: { reason: Error };
[AnalyticsError.INVALID_INDEXED_DB_CONTEXT]: { errorInfo: string };
}

export const ERROR_FACTORY = new ErrorFactory<AnalyticsError, ErrorParams>(
Expand Down
1 change: 1 addition & 0 deletions packages/firebase/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5083,6 +5083,7 @@ declare namespace firebase.analytics {
id?: string;
name?: string;
}
function isSupported(): boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will need a comment here to document what this does. Comments in this file are the source of our official documentation, see other methods/properties for format.

}

declare namespace firebase.auth.Auth {
Expand Down
9 changes: 9 additions & 0 deletions scripts/exp/extract-deps.helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export async function extractDependencies(
exportName,
jsBundle
);
console.log(dependencies);
return dependencies;
}

Expand All @@ -61,11 +62,17 @@ export async function extractDependenciesAndSize(
): Promise<ExportData> {
const input = tmp.fileSync().name + '.js';
const output = tmp.fileSync().name + '.js';
console.log(input);
console.log(output);
// jsBundle : /Users/xuechunhou/Desktop/Google/firebase-js-sdk/packages/firestore/dist/exp/index.js

// JavaScript content that exports a single API from the bundle
//beforeCOntent: export { Blob } from '/Users/xuechunhou/Desktop/Google/firebase-js-sdk/packages/firestore/dist/exp/index.js';
const beforeContent = `export { ${exportName} } from '${path.resolve(
jsBundle
)}';`;
console.log('beforeContent\n');
console.log(beforeContent);
fs.writeFileSync(input, beforeContent);

// Run Rollup on the JavaScript above to produce a tree-shaken build
Expand All @@ -76,6 +83,7 @@ export async function extractDependenciesAndSize(
await bundle.write({ file: output, format: 'es' });

const dependencies = extractDeclarations(output);
console.log(dependencies);

// Extract size of minified build
const afterContent = fs.readFileSync(output, 'utf-8');
Expand All @@ -99,6 +107,7 @@ export async function extractDependenciesAndSize(
*/
export function extractDeclarations(jsFile: string): MemberList {
const program = ts.createProgram([jsFile], { allowJs: true });

const sourceFile = program.getSourceFile(jsFile);
if (!sourceFile) {
throw new Error('Failed to parse file: ' + jsFile);
Expand Down
5 changes: 4 additions & 1 deletion scripts/exp/extract-deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@ GENERATE_DEPS_JS="$DIR/extract-deps.ts"
export TS_NODE_CACHE=NO
export TS_NODE_COMPILER_OPTIONS='{"module":"commonjs"}'
export TS_NODE_PROJECT="$DIR/../../config/tsconfig.base.json"

echo $TSNODE
echo $GENERATE_DEPS_JS
#Users/xuechunhou/Desktop/Google/firebase-js-sdk/node_modules/.bin/ts-node
#/Users/xuechunhou/Desktop/Google/firebase-js-sdk/scripts/exp/extract-deps.ts
$TSNODE $GENERATE_DEPS_JS "$@"
7 changes: 5 additions & 2 deletions scripts/report_binary_size.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const METRICS_SERVICE_URL = process.env.METRICS_SERVICE_URL;
function generateReportForCDNScripts() {
const reports = [];
const firebaseRoot = resolve(__dirname, '../packages/firebase');
// console.log(__dirname); // /Users/xuechunhou/Desktop/Google/firebase-js-sdk/scripts
// console.log(firebaseRoot); // /Users/xuechunhou/Desktop/Google/firebase-js-sdk/packages/firebase
const pkgJson = require(`${firebaseRoot}/package.json`);

const special_files = [
Expand All @@ -44,6 +46,7 @@ function generateReportForCDNScripts() {
component => `${firebaseRoot}/firebase-${component}.js`
)
];
//console.log(files);

for (const file of files) {
const { size } = fs.statSync(file);
Expand All @@ -70,7 +73,7 @@ function generateReportForNPMPackages() {
const packageInfo = JSON.parse(
execSync('npx lerna ls --json --scope @firebase/*').toString()
);

//console.log(packageInfo);
for (const package of packageInfo) {
// we traverse the dir in order to include binaries for submodules, e.g. @firebase/firestore/memory
// Currently we only traverse 1 level deep because we don't have any submodule deeper than that.
Expand All @@ -84,7 +87,7 @@ function generateReportForNPMPackages() {
}

const packageJson = require(packageJsonPath);

console.log(packageJson);
for (const field of fields) {
if (packageJson[field]) {
const filePath = `${path}/${packageJson[field]}`;
Expand Down