Skip to content
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

Issue 2393 - Add environment check to Analytics Module #3165

Merged
merged 47 commits into from
Jul 16, 2020

Conversation

XuechunHou
Copy link
Contributor

a fix for issue #2393 for analytics module.

Throw runtime error (UNSUPPORTED_BROWSER) on initialization of the instance when IndexedDB is not supported in some browser situations.

The fix is tested on Safari and Firefox private window rendering iframe with https://github.com/tomsun/firebase-js-sdk-securityerror-example provided in the issue conversation.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Jun 4, 2020

Binary Size Report

Affected SDKs

  • @firebase/analytics

    Type Base (c2b737b) Head (3035605) Diff
    esm2017 8.68 kB 9.66 kB +975 B (+11.2%)
    main 9.69 kB 10.9 kB +1.20 kB (+12.3%)
    module 9.37 kB 10.6 kB +1.22 kB (+13.0%)
  • @firebase/util

    Type Base (c2b737b) Head (3035605) Diff
    browser 19.6 kB 20.5 kB +921 B (+4.7%)
    esm2017 17.5 kB 18.3 kB +786 B (+4.5%)
    main 19.6 kB 20.5 kB +921 B (+4.7%)
    module 18.7 kB 19.5 kB +832 B (+4.5%)
  • firebase

    Type Base (c2b737b) Head (3035605) Diff
    firebase-analytics.js 26.6 kB 28.0 kB +1.37 kB (+5.1%)
    firebase.js 819 kB 820 kB +1.37 kB (+0.2%)

Test Logs

Copy link
Contributor

@hsubox76 hsubox76 left a comment

Choose a reason for hiding this comment

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

Looking good, left some comments.

Assuming this is WIP and you will remove extra code comments and console logs in a later pass.

@@ -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?

[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 FirebaseApp {
analytics(): FirebaseAnalytics;
}
}
function validateBrowserContext(): void {
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.


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?

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.

}
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.

@@ -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.

hsubox76
hsubox76 previously approved these changes Jul 7, 2020
@hsubox76 hsubox76 self-requested a review July 7, 2020 17:46
@hsubox76 hsubox76 dismissed their stale review July 7, 2020 17:50

Plan to move validation functions to util.

Copy link
Contributor

@hsubox76 hsubox76 left a comment

Choose a reason for hiding this comment

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

This looks good, thanks for all the changes and sorry for suggesting one more. The other comments are just grammar nits - "cookies are enabled/disabled" is usually how the functionality is referred to in communication even though I know the window property is cookieEnabled.

import {
isIndexedDBAvailable,
validateIndexedDBOpenable,
isCookieEnabled
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: areCookiesEnabled

[AnalyticsError.INVALID_INDEXED_DB_CONTEXT]:
"Environment doesn't support IndexedDB: {$errorInfo}. Wrap initialization of analytics in analytics.isSupported() to prevent intialization in unsupported environments",
[AnalyticsError.COOKIE_NOT_ENABLED]:
'Cookie not enabled in this browser environment. Analytics requires cookies to be enabled.'
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: "Cookies are not"

'IndexedDB is not supported by current browswer',
[AnalyticsError.INVALID_INDEXED_DB_CONTEXT]:
"Environment doesn't support IndexedDB: {$errorInfo}. Wrap initialization of analytics in analytics.isSupported() to prevent intialization in unsupported environments",
[AnalyticsError.COOKIE_NOT_ENABLED]:
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: COOKIES_NOT_ENABLED

[AnalyticsError.INDEXED_DB_UNSUPPORTED]:
'IndexedDB is not supported by current browswer',
[AnalyticsError.INVALID_INDEXED_DB_CONTEXT]:
"Environment doesn't support IndexedDB: {$errorInfo}. Wrap initialization of analytics in analytics.isSupported() to prevent intialization in unsupported environments",
Copy link
Contributor

Choose a reason for hiding this comment

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

Line wrap by breaking up string ("" + ""), and second "initialization" (after "prevent") missing a letter.

* This method also validates browser context for indexedDB by opening a dummy indexedDB database and throws AnalyticsError.INVALID_INDEXED_DB_CONTEXT
* if errors occur during the database open operation.
*/
export async function validateInitializationEnvironment(): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

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

First, sorry for so many changes. Figuring this functionality out is kind of uncharted territory so there's been a lot of trying things out and undoing them if they don't work.

Since there's async and sync parts I think maybe we shouldn't have a single function for this anymore.

  • I would suggest the first 2 if blocks in factory() just as they are here (since they can actually block initialization, why not let them?)
  • And then for the validateIndexedDBOpenable() check, call it with a chained .catch() where you add the analytics-specific text and re-throw the error just as you do here.

Copy link
Contributor

@hsubox76 hsubox76 left a comment

Choose a reason for hiding this comment

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

Looks just about ready!

  • One comment about maybe getting rid of eslint comment?
  • Get rid of 2 stray auth files? (maybe came from a merge? checkout from origin/master)
  • Change PR title to be descriptive of content: "Add environment check to analytics"?

}
if (!isIndexedDBAvailable()) {
throw ERROR_FACTORY.create(AnalyticsError.INDEXED_DB_UNSUPPORTED);
}
// Async but non-blocking.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Copy link
Contributor

Choose a reason for hiding this comment

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

Is eslint ok now if we get rid of this comment?

@XuechunHou XuechunHou changed the title Issue 2393 fix - analytics module Add environment check to analytics Jul 14, 2020
@XuechunHou XuechunHou changed the title Add environment check to analytics Issue 2393 - Add environment check to analytics Jul 14, 2020
@XuechunHou XuechunHou changed the title Issue 2393 - Add environment check to analytics Issue 2393 - Add environment check to Analytics Module Jul 14, 2020
@XuechunHou XuechunHou merged commit 02419ce into master Jul 16, 2020
@XuechunHou XuechunHou deleted the issue-2393-analytics branch July 16, 2020 20:43
@google-oss-bot google-oss-bot mentioned this pull request Jul 22, 2020
@firebase firebase locked and limited conversation to collaborators Aug 16, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants