Is there someway to disable all firebase logging to console? - javascript

I have created some unit tests for my firebase security rules. Part of this testing is trying to do illegal operations and asserting that they fail.
My problem has to do with noise; when I run the tests using nodeunit, the firebase client spits out several logs similar to this:
FIREBASE WARNING: set at /user failed: permission_denied
I do not want this output when intentionally doing illegal operations as it just results in noise and confusion.

These days there is an option to set the log level on the global firebase object:
import firebase from 'firebase/app';
firebase.setLogLevel('silent')

In our testing suite, we rewrite process.stderr.write to only ignore firebase warnings like so:
Javascript
process.stderr.write = (function(write) {
return function() {
if (!arguments[0].includes("FIREBASE WARNING"))
write.apply(process.stderr, arguments);
};
}(process.stderr.write));
Typescript (including tslint fix)
process.stderr.write = (() => {
// tslint:disable-next-line:no-unbound-method
const write = process.stderr.write;
return function () {
if (!(arguments[0] as string).includes("FIREBASE WARNING")) {
return write.apply(process.stderr, arguments);
}
};
})();

There is no way to disable the security warnings as they are emitted asynchronously by the Firebase SDK. I worked around this by adding a message before the errors:
>>> An intentional security error should be printed after this line...

As Kato said, there doesn't appear to be an official way to disable it. That said, if you really want to, it takes 2 seconds to go into the source, Ctrl+F for "WARNING", and comment out this line:
"undefined"!==typeof console.warn?console.warn(b):console.log(b)

Related

null is not an object (evaluating 'RCTAsyncStorage.multiMerge')

I recently upgraded to Expo SDK 43.
I am now getting this error:
The line of code throwing it is:
if (!RCTAsyncStorage.multiMerge) {
I am on the latest version of AsyncStorage.
This seems to be due to my usage of firebase-js-sdk.
Unfortunately as this is an iOS/Android/Web project, it's necessary.
When I mock my Firebase exports, everything works:
const auth = () => {};
const analytics = () => {};
export default { auth, analytics };
But when I use the firebase-js-sdk functions, I get the above message.
This code causes an error (whichever version of auth I use)
let auth = initializeAuth(config, {
persistence: getReactNativePersistence(AsyncStorage),
});
//let auth = getAuth(config);
let analytics = getAnalytics(config);
export default { auth, analytics };
You could avoid that specific error by adding optional chaining (the question mark '?'):
if (!RCTAsyncStorage?.multiMerge) {
It will shortcircuit to undefined (thus making the if false) instead of throwing error from trying to check in the null object.
As to why RCTAsyncStorage would be null, you would have to check where you first get/declare it, and traceback to the point it didn't load, maybe you are using something conflicting from firebase-js-sdk.
Also multiMerge might not be supported always as mentioned in the docs:
multiMerge
[...] NOTE: This is not supported by all native implementations.

Firestore SDK cannot mock DocumentSnapshot

So I am trying to create a unit test for a firestore trigger, triggered by an onCreate event. The firebase documentation said to do this as so: Firebase Unit Testing Background Functions
I copy the documentation pretty closely:
const snapshot = test.firestore.makeDocumentSnapshot(
{owner: 'testUserA', text: 'response from test user a'},
'users/testUserA/questions/testQuestion/responses/testResponse'
);
This line gives the error:
UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token u in JSON at position 0
At first I thought it might have to do with the refPath because it starts with u, but after changing it, the error is identical, so I assume it has to do with the first parameter, which seems like correct json, but apparently not. I'm kind of stumped.
Any ideas? Thanks!
Do you have test.cleanup() in any other testing cases before you use test.firestore.makeDocumentSnapshot()? If any, remove them and run the test again

Overriding Object.prototype.get to Prevent Null Check Issues in Large App

I realize this is not recommended by the JS community but I think have a good use case for overriding the Object.prototype so that accessing properties of undefined objects returns undefined instead of throwing an app crashing error.
Little background information:
Working with a large app (about 200k lines of code)
App is extremely configurable with loads of options - there's no way of testing every possibility
Angular 2/Ionic 2 project
Basically, I'd like to make it so that the following code console logs 'undefined' instead of generating an error:
Pseudo code:
Object.defineProperty(Object.prototype, Object.prototype.get, (val) => {
try {
console.log(val);
} catch (e) {
console.log('Attempted to access undefined property');
}
});
const obj = {
a: 'b'
};
console.log(obj.a.b.c); // should log undefined but actually generates an app freezing issue
Questions:
How can I make this work? Is there another way I can prevent null check errors across the entire app without adding too much code? Is there a generic fix for making it so that these null check errors do not crash the Angular/Ionic app?

TypeError: Cannot read property 'toBeA' of undefined

I am trying to test my code using expect in nodejs. I required expect in code and I wanted to use a feature of expect called toBeA(). But unfortunately I
am receiving error and unable to solve it. So,I am posting it here.
const utils = require('./utils');
const expect = require('expect');
it('should add two numbers', () => {
var result = utils.add(33,17);
expect(result).toBe(50).toBeA('number');
});
This is my utils.js file
module.exports.add = (a,b) => {
return a+b;
};
When I run the code I receive this error
TypeError: Cannot read property 'toBeA' of undefined
You cannot chain tests. toBe doesn't return anything, hence the error. You want
expect(result).toBe(50);
expect(result).toBeA('number');
(although the first one implies the other so you might as well omit it)
This works fine instead of toBeA()
expect(typeof result).toBe('number');
The expect assertion library has changed ownership. It was handed over to the Jest team, who in their infinite wisdom, created a new API.
You can still install expect as before, "npm install expect --save-dev", which is currently at version 21.2.1. Most methods names will remain unchanged except for a few, including 'toExist(), toBeA()'.
when use npm i expect --save-dev command for install expect, automatically install last version of expect. in last version chain do not work.
for solve this problem you should use below command:
npm i expect#1.20.2
in this version you can use chain expect like toNotBe.

Bad idea to leave "console.log()" calls in your production JavaScript code?

I have a bunch of console.log() calls in my JavaScript.
Should I comment them out before I deploy to production?
I'd like to just leave them there, so I don't have to go to the trouble of re-adding the comments later on if I need to do any more debugging. Is this a bad idea?
It will cause Javascript errors, terminating the execution of the block of Javascript containing the error.
You could, however, define a dummy function that's a no-op when Firebug is not active:
if(typeof console === "undefined") {
console = { log: function() { } };
}
If you use any methods other than log, you would need to stub out those as well.
As others have already pointed it, leaving it in will cause errors in some browsers, but those errors can be worked around by putting in some stubs.
However, I would not only comment them out, but outright remove those lines. It just seems sloppy to do otherwise. Perhaps I'm being pedantic, but I don't think that "production" code should include "debug" code at all, even in commented form. If you leave comments in at all, those comments should describe what the code is doing, or the reasoning behind it--not blocks of disabled code. (Although, most comments should be removed automatically by your minification process. You are minimizing, right?)
Also, in several years of working with JavaScript, I can't recall ever coming back to a function and saying "Gee, I wish I'd left those console.logs in place here!" In general, when I am "done" with working on a function, and later have to come back to it, I'm coming back to fix some other problem. Whatever that new problem is, if the console.logs from a previous round of work could have been helpful, then I'd have spotted the problem the first time. In other words, if I come back to something, I'm not likely to need exactly the same debug information as I needed on previous occasions.
Just my two cents... Good luck!
Update after 13 years
I've changed my mind, and now agree with the comments that have accumulated on this answer over the years.
Some log messages provide long-term value to an application, even a client-side JavaScript application, and should be left in.
Other log messages are low-value noise and should be removed, or else they will drown out the high-value messages.
If you have a deployment script, you can use it to strip out the calls to console.log (and minify the file).
While you're at it, you can throw your JS through JSLint and log the violations for inspection (or prevent the deployment).
This is a great example of why you want to automate your deployment. If your process allows you to publish a js file with console.logs in it, at some point you will do it.
To my knowledge there is no shorter method of stubbing out console.log than the following 45 characters:
window.console||(console={log:function(){}});
That's the first of 3 different versions depending on which console methods you want to stub out all of them are tiny and all have been tested in IE6+ and modern browsers.
The other two versions cover varying other console methods. One covers the four basics and the other covers all known console methods for firebug and webkit. Again, in the tiniest file sizes possible.
That project is on github: https://github.com/andyet/ConsoleDummy.js
If you can think of any way to minimize the code further, contributions are welcomed.
-- EDIT -- May 16, 2012
I've since improved on this code. It's still tiny but adds the ability to turn the console output on and off: https://github.com/HenrikJoreteg/andlog
It was featured on The Changelog Show
You should at least create a dummy console.log if the object doesn't exist so your code won't throw errors on users' machines without firebug installed.
Another possibility would be to trigger logging only in 'debug mode', ie if a certain flag is set:
if(_debug) console.log('foo');
_debug && console.log('foo');
Hope it helps someone--I wrote a wrapper for it a while back, its slightly more flexible than the accepted solution.
Obviously, if you use other methods such as console.info etc, you can replicate the effect. when done with your staging environment, simply change the default C.debug to false for production and you won't have to change any other code / take lines out etc. Very easy to come back to and debug later on.
var C = {
// console wrapper
debug: true, // global debug on|off
quietDismiss: false, // may want to just drop, or alert instead
log: function() {
if (!C.debug) return false;
if (typeof console == 'object' && typeof console.log != "undefined") {
console.log.apply(this, arguments);
}
else {
if (!C.quietDismiss) {
var result = "";
for (var i = 0, l = arguments.length; i < l; i++)
result += arguments[i] + " ("+typeof arguments[i]+") ";
alert(result);
}
}
}
}; // end console wrapper.
// example data and object
var foo = "foo", bar = document.getElementById("divImage");
C.log(foo, bar);
// to surpress alerts on IE w/o a console:
C.quietDismiss = true;
C.log("this won't show if no console");
// to disable console completely everywhere:
C.debug = false;
C.log("this won't show ever");
this seems to work for me...
if (!window.console) {
window.console = {
log: function () {},
group: function () {},
error: function () {},
warn: function () {},
groupEnd: function () {}
};
}
Figured I would share a different perspective. Leaving this type of output visible to the outside world in a PCI application makes you non-compliant.
I agree that the console stub is a good approach. I've tried various console plugins, code snippets, including some fairly complex ones. They all had some problem in at least one browser, so I ended up going with something simple like below, which is an amalgamation of other snippets I've seen and some suggestions from the YUI team. It appears to function in IE8+, Firefox, Chrome and Safari (for Windows).
// To disable logging when posting a production release, just change this to false.
var debugMode = false;
// Support logging to console in all browsers even if the console is disabled.
var log = function (msg) {
debugMode && window.console && console.log ? console.log(msg) : null;
};
Note: It supports disabling logging to the console via a flag. Perhaps you could automate this via build scripts too. Alternatively, you could expose UI or some other mechanism to flip this flag at run time. You can get much more sophisticated of course, with logging levels, ajax submission of logs based on log threshold (e.g. all Error level statements are transmitted to the server for storage there etc.).
Many of these threads/questions around logging seem to think of log statements as debug code and not code instrumentation. Hence the desire to remove the log statements. Instrumentation is extremely useful when an application is in the wild and it's no longer as easy to attach a debugger or information is fed to you from a user or via support. You should never log anything sensitive, regardless of where it's been logged to so privacy/security should not be compromised. Once you think of the logging as instrumentation it now becomes production code and should be written to the same standard.
With applications using ever more complex javascript I think instrumentation is critical.
As other have mentions it will thrown an error in most browsers. In Firefox 4 it won't throw an error, the message is logged in the web developer console (new in Firefox 4).
One workaround to such mistakes that I really liked was de&&bug:
var de = true;
var bug = function() { console.log.apply(this, arguments); }
// within code
de&&bug(someObject);
A nice one-liner:
(!console) ? console.log=function(){} : console.log('Logging is supported.');
Yes, it's bad idea to let them running always in production.
What you can do is you can use console.debug which will console ONLY when the debugger is opened.
https://developer.mozilla.org/en-US/docs/Web/API/console/debug

Categories

Resources