diff --git a/packages/app/index.ts b/packages/app/index.ts index 990b18c5187..631b6155016 100644 --- a/packages/app/index.ts +++ b/packages/app/index.ts @@ -17,45 +17,53 @@ import { FirebaseNamespace } from '@firebase/app-types'; import { createFirebaseNamespace } from './src/firebaseNamespace'; +import { isNode, isBrowser } from '@firebase/util'; +import { Logger } from '@firebase/logger'; -// Node detection logic from: https://github.com/iliakan/detect-node/ -let isNode = false; -try { - isNode = - Object.prototype.toString.call(global.process) === '[object process]'; -} catch (e) {} - -isNode && - console.warn(` -Warning: This is a browser-targeted Firebase bundle but it appears it is being -run in a Node environment. If running in a Node environment, make sure you -are using the bundle specified by the "main" field in package.json. - -If you are using Webpack, you can specify "main" as the first item in -"resolve.mainFields": -https://webpack.js.org/configuration/resolve/#resolvemainfields - -If using Rollup, use the rollup-plugin-node-resolve plugin and set "module" -to false and "main" to true: -https://github.com/rollup/rollup-plugin-node-resolve -`); +const logger = new Logger('@firebase/app'); // Firebase Lite detection -if (self && 'firebase' in self) { - console.warn(` +if (isBrowser() && 'firebase' in self) { + logger.warn(` Warning: Firebase is already defined in the global scope. Please make sure Firebase library is only loaded once. `); const sdkVersion = ((self as any).firebase as FirebaseNamespace).SDK_VERSION; if (sdkVersion && sdkVersion.indexOf('LITE') >= 0) { - console.warn(` + logger.warn(` Warning: You are trying to load Firebase while using Firebase Performance standalone script. You should load Firebase Performance with this instance of Firebase to avoid loading duplicate code. `); } } -export const firebase = createFirebaseNamespace(); +const firebaseNamespace = createFirebaseNamespace(); +const initializeApp = firebaseNamespace.initializeApp; + +firebaseNamespace.initializeApp = function() { + // Environment check before initializing app + // Do the check in initializeApp, so people have a chance to disable it by setting logLevel + // in @firebase/logger + if (isNode()) { + logger.warn(` + Warning: This is a browser-targeted Firebase bundle but it appears it is being + run in a Node environment. If running in a Node environment, make sure you + are using the bundle specified by the "main" field in package.json. + + If you are using Webpack, you can specify "main" as the first item in + "resolve.mainFields": + https://webpack.js.org/configuration/resolve/#resolvemainfields + + If using Rollup, use the rollup-plugin-node-resolve plugin and set "module" + to false and "main" to true: + https://github.com/rollup/rollup-plugin-node-resolve + `); + } + + return initializeApp.apply(undefined, arguments); +}; + +export const firebase = firebaseNamespace; export default firebase; diff --git a/packages/app/package.json b/packages/app/package.json index fecab9b5066..9b909bd3425 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -26,6 +26,7 @@ "dependencies": { "@firebase/app-types": "0.4.0", "@firebase/util": "0.2.14", + "@firebase/logger": "0.1.13", "tslib": "1.9.3", "dom-storage": "2.1.0", "xmlhttprequest": "1.8.0" diff --git a/packages/util/index.ts b/packages/util/index.ts index 10df6e59b47..47ee88e3f3f 100644 --- a/packages/util/index.ts +++ b/packages/util/index.ts @@ -15,67 +15,18 @@ * limitations under the License. */ -export { assert, assertionError } from './src/assert'; -export { base64, base64Decode, base64Encode } from './src/crypt'; -export { CONSTANTS } from './src/constants'; -export { deepCopy, deepExtend, patchProperty } from './src/deepCopy'; -export { Deferred } from './src/deferred'; -export { - getUA, - isMobileCordova, - isNodeSdk, - isReactNative -} from './src/environment'; -export { - ErrorFactory, - ErrorMap, - FirebaseError, - StringLike -} from './src/errors'; -export { jsonEval, stringify } from './src/json'; -export { - decode, - isAdmin, - issuedAtTime, - isValidFormat, - isValidTimestamp -} from './src/jwt'; -export { - clone, - contains, - every, - extend, - findKey, - findValue, - forEach, - getAnyKey, - getCount, - getValues, - isEmpty, - isNonNullObject, - map, - safeGet -} from './src/obj'; -export { querystring, querystringDecode } from './src/query'; -export { Sha1 } from './src/sha1'; -export { - async, - CompleteFn, - createSubscribe, - ErrorFn, - Executor, - NextFn, - Observable, - Observer, - PartialObserver, - Subscribe, - Unsubscribe -} from './src/subscribe'; -export { - errorPrefix, - validateArgCount, - validateCallback, - validateContextObject, - validateNamespace -} from './src/validation'; -export { stringLength, stringToByteArray } from './src/utf8'; +export * from './src/assert'; +export * from './src/crypt'; +export * from './src/constants'; +export * from './src/deepCopy'; +export * from './src/deferred'; +export * from './src/environment'; +export * from './src/errors'; +export * from './src/json'; +export * from './src/jwt'; +export * from './src/obj'; +export * from './src/query'; +export * from './src/sha1'; +export * from './src/subscribe'; +export * from './src/validation'; +export * from './src/utf8'; diff --git a/packages/util/src/environment.ts b/packages/util/src/environment.ts index 41dbca41fdc..321b593b1b7 100644 --- a/packages/util/src/environment.ts +++ b/packages/util/src/environment.ts @@ -21,7 +21,7 @@ import { CONSTANTS } from './constants'; * Returns navigator.userAgent string or '' if it's not defined. * @return {string} user agent string */ -export const getUA = function() { +export function getUA(): string { if ( typeof navigator !== 'undefined' && typeof navigator['userAgent'] === 'string' @@ -30,7 +30,7 @@ export const getUA = function() { } else { return ''; } -}; +} /** * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device. @@ -40,30 +40,53 @@ export const getUA = function() { * * @return {boolean} isMobileCordova */ -export const isMobileCordova = function() { +export function isMobileCordova(): boolean { return ( typeof window !== 'undefined' && !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) && /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA()) ); -}; +} + +/** + * Detect Node.js. + * + * @return {boolean} True if Node.js environment is detected. + * Node detection logic from: https://github.com/iliakan/detect-node/ + */ +export function isNode(): boolean { + try { + return ( + Object.prototype.toString.call(global.process) === '[object process]' + ); + } catch (e) { + return false; + } +} + +/** + * Detect Browser Environment + */ +export function isBrowser(): boolean { + return typeof window !== 'undefined'; +} /** * Detect React Native. * * @return {boolean} True if ReactNative environment is detected. */ -export const isReactNative = function() { +export function isReactNative(): boolean { return ( typeof navigator === 'object' && navigator['product'] === 'ReactNative' ); -}; +} /** - * Detect Node.js. + * Detect whether the current SDK build is the Node version. * - * @return {boolean} True if Node.js environment is detected. + * @return {boolean} True if it's the Node SDK build. */ -export const isNodeSdk = function() { +export function isNodeSdk(): boolean { return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true; -}; +}