web3.eth.accounts[0] returns undefined - javascript

I am new to solidity and was exploring it through a simple webapp. I have a web app which accepts some details and a button pressing which the details should be deployed to the block created by the smart contract. The details are successfully deployed from the remix IDE but give the following exception when entering through the web app.
inpage.js:1 Uncaught Error: Invalid number of arguments to Solidity function
at Object.InvalidNumberOfSolidityArgs (inpage.js:1)
at u.validateArgs (inpage.js:1)
at u.toPayload (inpage.js:1)
at u.sendTransaction (inpage.js:1)
at u.execute (inpage.js:1)
at HTMLButtonElement.<anonymous> ((index):231)
at HTMLButtonElement.dispatch (jquery-3.2.1.slim.min.js:3)
at HTMLButtonElement.q.handle (jquery-3.2.1.slim.min.js:3)
On surfing the internet I found that this could be because the web3.eth.accounts[0] returns 'undefined' which is what is happening in my case.
On the contrary though on displaying web3.eth on the console it does show accounts and the MetaMask address too at index 0.
I read it may be because web3js 1.0 might not be completely supported by MetaMask yet but I am unable to find a solution to it.
Also how to check the version of web3 I am using and how to deprecate to lower if necessary.
This is how I try to access the web3.eth.accounts[0]
web3.eth.defaultAccount = web3.eth.accounts[0];
console.log(web3.eth.defaultAccount); // returns undefined
I also tried the following method but to no avail:
var myAccount;
web3.eth.getAccounts(function(err,res){
if(!err)
{
myAccount = res;
console.log(myAccount);
}
});
This returns the account address but the myAccount variable again returns 'undefined' when used outside the getAccounts method. Also writing the further logic inside the if part does not help giving the above mentioned exception.
I have tried a few things but unable to find the solution. Please guide and correct if I have miss-understood anything.
EDIT
You can find the source code here.
https://github.com/anishsamant/Solidity-Demo
Refer Courses.sol for solidity file
Refer index.html for web app.

Methods in web3 such as getAccounts are asynchronous.
Note
web3 version 1.x.x return promises. So you use promises and you can also implement it with the async/await syntax.
web3 versions 0.x.x do not return promises, you can only use callbacks.
Code for web3 versions 1.x.x (I can only assume you might be using).
const myFunc = async () => {
try {
const myAccounts = await web3.eth.getAccounts();
console.log(myAccounts)
return myAccounts;
} catch (err) {
console.log(err);
}
}
myFunc()

Related

How to check if an exception is a FirebaseError / FirebaseAuthError in TypeScript

I'm trying to implement Firebase authentication and user creation on our server, working on TypeScript.
I'm creating a new user, and I have wrapped the whole creation inside a try-catch block. I'm trying to catch several exceptions, one of them being exception thrown by Firebase.
The problem is that I can't check if the exception was thrown by the Firebase, or if it's another type of exception.
Other answers to similar kind of questions suggest to check if the exception is an instance of FirebaseError:
let firebaseUser;
try {
firebaseUser = await firebase.auth().createUser({
email: email,
password: password,
});
// Other code here
} catch (error) {
if(error instanceof FirebaseError){
// handle FirebaseError here
}
}
The problem is, that when there is an error in the createUser function, the error is an instance of FirebaseAuthError, not FirebaseError, so this check fails.
I tried to switch it to FirebaseAuthError and import the FirebaseAuthError as well, but I get an error message:
Package subpath './lib/utils/error' is not defined by "exports" in
\node_modules\firebase-admin\package.json
So what would be the correct way to check that the caught exception is thrown by FirebaseAuth?
I think the best thing you can do, is writing a type guard to ensure your error is a FirebaseAuthError that you will import using import type. I checked, and it seems that it's because the library doesn't export it.
You can freely benefit from the type used by firebase, however, as the module is not listed in the exports, you won't be able to use it at runtime. the import type syntax allows you to still use it during development, but it will be completely ignored at build time.
That means you can't use instanceof FirebaseAuthError as only the type is imported, and you can't use instanceof on something else than a class.
I'm not sure about the following statement, but I guess that every error prefixed by auth/ seem to be a FirebaseAuthError.
Thus, you could write a type guard as follows:
import type { FirebaseAuthError } from 'firebase-admin/lib/utils/error';
function isFirebaseAuthError(error: FirebaseError): error is FirebaseAuthError {
return error.code.startsWith('auth/');
}

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 (7.14.3) INTERNAL ASSERTION FAILED: value must be undefined or Uint8Array

My script keeps raising this error. The code I've written is for testing Firestore security rules.
I basically wanted to test my firestore security while adding the javascript functions to it. It is possible to write the rules in firestore console and save them then and there but I wanted to use an IDE - VS code.
I wanted to know how to fix "FIRESTORE (7.14.3) INTERNAL ASSERTION FAILED: value must be undefined or Uint8Array". I've updated my npm and also tried an answer I found on Github which said for me to install first "npm i jest-environment-uint8array". It did not work. I have also tried to use " TextEncoder"
Like: var uint8array = new TextEncoder("utf-8").encode("Posts");
var string = new TextDecoder("utf-8").decode(uint8array);
It did not work as well. I would really appreciate it if you guys answered me thoroughly since I am just a novice.
My code for testing is
const { setup, teardown } = require("./helpers");
describe("General Safety Rules", () => {
afterEach(async () => {
await teardown();
});
test("should deny a read to the posts collection", async () => {
const db = await setup();
const postsRef = db.collection("Posts");
await expect(postsRef.get()).toDeny();
});
});
My helper js has basically the setup and the teardown for after when my code finishes.
const firebase = require("#firebase/testing");
const fs = require("fs");
module.exports.setup = async (auth, data) => {
const projectId = `rules-spec-${Date.now()}`;
const app = firebase.initializeTestApp({
projectId,
auth
});
const db = app.firestore();
// Apply the test rules so we can write documents
await firebase.loadFirestoreRules({
projectId,
rules: fs.readFileSync("firestore-test.rules", "utf8")
});
// write mock documents if any
if (data) {
for (const key in data) {
const ref = db.doc(key); // This means the key should point directly to a document
await ref.set(data[key]);
}
}
// Apply the actual rules for the project
await firebase.loadFirestoreRules({
projectId,
rules: fs.readFileSync("firestore.rules", "utf8")
});
return db;
};
module.exports.teardown = async () => {
// Delete all apps currently running in the firebase simulated environment
Promise.all(firebase.apps().map(app => app.delete()));
};
The error is:
jest ./spec
(node:8200) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
FAIL spec/collections.spec.js (10.284 s)
General Safety Rules
× should deny a read to the posts collection (4598 ms)
× should deny a write to users even when logged in (131 ms)
● General Safety Rules › should deny a read to the posts collection
FIRESTORE (7.14.3) INTERNAL ASSERTION FAILED: value must be undefined or Uint8Array
at fail (node_modules/#firebase/firestore/src/util/assert.ts:39:9)
at hardAssert (node_modules/#firebase/firestore/src/util/assert.ts:53:5)
at JsonProtoSerializer.fromBytes (node_modules/#firebase/firestore/src/remote/serializer.ts:250:7)
at JsonProtoSerializer.fromWatchChange (node_modules/#firebase/firestore/src/remote/serializer.ts:431:32)
at PersistentListenStream.onMessage (node_modules/#firebase/firestore/src/remote/persistent_stream.ts:568:41)
at node_modules/#firebase/firestore/src/remote/persistent_stream.ts:448:21
at node_modules/#firebase/firestore/src/remote/persistent_stream.ts:501:18
at node_modules/#firebase/firestore/src/util/async_queue.ts:358:14
● General Safety Rules › should deny a write to users even when logged in
FIRESTORE (7.14.3) INTERNAL ASSERTION FAILED: value must be undefined or Uint8Array
at fail (node_modules/#firebase/firestore/src/util/assert.ts:39:9)
at hardAssert (node_modules/#firebase/firestore/src/util/assert.ts:53:5)
at JsonProtoSerializer.fromBytes (node_modules/#firebase/firestore/src/remote/serializer.ts:250:7)
at JsonProtoSerializer.fromWatchChange (node_modules/#firebase/firestore/src/remote/serializer.ts:431:32)
at PersistentListenStream.onMessage (node_modules/#firebase/firestore/src/remote/persistent_stream.ts:568:41)
at node_modules/#firebase/firestore/src/remote/persistent_stream.ts:448:21
at node_modules/#firebase/firestore/src/remote/persistent_stream.ts:501:18
at node_modules/#firebase/firestore/src/util/async_queue.ts:358:14
console.error
[2020-05-20T13:13:11.851Z] #firebase/firestore: Firestore (7.14.3): FIRESTORE (7.14.3) INTERNAL ASSERTION FAILED: value must be undefined or Uint8Array
at Logger.defaultLogHandler [as _logHandler] (node_modules/#firebase/logger/src/logger.ts:115:57)
at logError (node_modules/#firebase/firestore/src/util/log.ts:45:20)
at fail (node_modules/#firebase/firestore/src/util/assert.ts:34:3)
at hardAssert (node_modules/#firebase/firestore/src/util/assert.ts:53:5)
at JsonProtoSerializer.fromBytes (node_modules/#firebase/firestore/src/remote/serializer.ts:250:7)
at JsonProtoSerializer.fromWatchChange (node_modules/#firebase/firestore/src/remote/serializer.ts:431:32)
Test Suites: 1 failed, 1 total
Tests: 2 failed, 2 total
Snapshots: 0 total
Time: 18.711 s
Ran all test suites matching /.\\spec/i.
(node:8200) UnhandledPromiseRejectionWarning: FirebaseError: Caught error after test environment was torn down
The client has already been terminated.
(node:8200) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:8200) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
It seems to be a compatibility issue between the latest #firebase/testing#0.19.4 version and the internally used firebase#7.14.4 version. I had the same error and got it working with a temporary workaround.
Try downgrading your #firebase/testing version to ^0.15.0. After a quick npm i it worked for me. You can still upgrade to latest versions later as soon as they fix the current compatibility issues.
I will update my answer as soon as this happens.
Update:
This is the issue I created on the firebase-js-sdk GitHub page https://github.com/firebase/firebase-js-sdk/issues/3096.
Seems to be related to a bug in the testing framework Jest. The issue describes a workaround which does not require to downgrade.
I will update my answer as soon as the workaround is not required anymore.
Here's the Firebase issue:
https://github.com/firebase/firebase-js-sdk/issues/3096
Apparently it's caused by a bug in Jest ...
https://github.com/facebook/jest/issues/7780
... that includes this workaround:
https://github.com/facebook/jest/issues/7780#issuecomment-615890410
Steps to reproduce and fix ...
https://github.com/dconeybe/FirebaseJsBug3096
You can solve this problem simply by adding the following JSDOC comment to the top of your test file, which prevents Jest running your tests with JSDOM.
In spec/collections.spec.js:
/**
* #jest-environment node
*/
describe("my rules", () => {
// ...
});
The underlying issue is an incompatibility between jsdom and an internal assertion used by the firebase library, documented here: https://github.com/nodejs/node/issues/20978
The workaround noted by Tony O'Hagan (here) allows the tests to run in the JSDOM environment but the solution is pretty complex. If you're only testing Firestore security rules then you don't need JSDOM.
Update: Jest 27 (May 2021) changed Jest's default behavior to run in the Node environment instead of JSDOM

sqlite3 database: TypeError: Cannot read property of undefined

I have a Node.js script that used to work, but after I switched to another VM it does not work anymore. Can anyone see what the problem is? Here is the function, db is a database:
this.start = function() {
logger.debug('Starting up.');
db.serialize(() => {
db.run("DELETE FROM jobs WHERE status = 'failed'")
.run("UPDATE jobs SET status = 'queued'", (err) => {
if (err) {
logger.error(err.message);
} else {
logger.info('done');
}
});
});
}
Now I get the following error:
TypeError: Cannot read property 'run' of undefined
at Database.db.serialize ()
at TransactionDatabase.serialize
at module.exports.start
at Object.<anonymous>
...
The error is pointing at the second ".run".
My Node.js version is 10.4.1, sqlite3 version 3.8.2.
What am I missing? Some module?
I think I found the answer. Chaining run() runs the queries nearly at the same time. According to this answer, the function run() starts the query, but returns immediately.
However, if you serialize and chain, those two methods cannot be used at the same time. You are trying run queries sequentialy, but also at the same time.
Although, depending on your needs, you can nest serialize, parallelize or callbacks, as shown in the "control flow" doc.
I guess the method serialize() "locks" chaining by changing the return value of run() to undefined.

Invalid Chai property: called. Did you mean "all"?

I am trying to test my node.js code using Mocha, Sinon, and chai.
var callback = function (err, resultSet) {
should.exist(resultSet);
stubbedExecuteSqlQuery.should.be.called;
done();
};
stubbedExecuteSqlQuery.yields(null, expectedResultSet);
db.getResults(param1,param2, user, callback);
when the above code gets executed, it throws an error :
Invalid Chai property: called. Did you mean "all"?
The code used to work fine on chai version ^3.5.0 but after my recent package upgrade to ^4.1.2 the code has stopped working and has started throwing such errors.
I tried searching for it on the internet but could not find any useful information.
Any help will be appreciated. Thanks in advance!
I had a similar issue, I think it had something to do with using .yields
I ended up using .calledOnce . Try the following:
assert(stubbedExecuteSqlQuery.calledOnce);
The upside with this is that if needed you can do .calledTwice etc..

Categories

Resources