fastify + mongo = why nothing is stored inside database? - mongodb

I am building a fastify application with mongodb. I've created this package.json file with a script to run mongo.
{
"dependencies": {
"#fastify/mongodb": "5.0.0",
"fastify": "4.11.0"
},
"scripts": {
"start": "node server.js",
"start-mongo": "docker run -d --name my-mongo -p 27017:27017 mongo",
}
}
And with npm run start-mongo I run mongo exposing port 27017. Then, ... this is fastify part.
const fastify = require('fastify')({logger: true})
fastify.register(require('#fastify/mongodb'), {
forceClose: true,
url: 'mongodb://localhost:27017/library'
})
fastify.get('/books', async(request, reply) => {
const books = await fastify.mongo.db
.collection('books')
.find()
reply.send(books)
});
fastify.post('/books', async(request, reply) => {
const result = await fastify
.mongo.db
.collection('books')
.insertOne(request.body)
reply.send({
message: 'book added',
id: result.insertId
})
})
GET /books:
{"_events":{},"_eventsCount":0}
POST /books
curl -H 'Content-Type: application/json' -X POST http://localhost:3000/books -d '{"message":"prova"}'
returns
{"message":"book added"}
It is strange because response should contain also id. But it doesnt.
reply.send({
message: 'book added',
id: result.insertId
})
This means that
const result = await fastify
.mongo.db
.collection('books')
.insertOne(request.body)
doesnt store the book. Any error is displayed and GET always return:
{"_events":{},"_eventsCount":0}
What's wrong?
--
I've also created mongo with docker-compose:
version: '3.1'
services:
mongo:
image: mongo
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
but it returns:
{
statusCode: 500,
code: '13',
error: 'Internal Server Error',
message: 'command insert requires authentication'
}
{
statusCode: 500,
code: '13',
error: 'Internal Server Error',
message: 'command find requires authentication'
}
I updated code from
fastify.register(require('#fastify/mongodb'), {
forceClose: true,
url: 'mongodb://localhost:27017/library'
})
to
fastify.register(require('#fastify/mongodb'), {
forceClose: true,
url: 'mongodb://root:example#localhost:27017/library'
})
but returns:
(node:86146) UnhandledPromiseRejectionWarning: MongoServerError: Authentication failed.
at Connection.onMessage (/Users/simonegentili/Development/github.com/sensorario/youtube.poliglotta/node_modules/mongodb/lib/cmap/connection.js:227:30)
at MessageStream.<anonymous> (/Users/simonegentili/Development/github.com/sensorario/youtube.poliglotta/node_modules/mongodb/lib/cmap/connection.js:60:60)
at MessageStream.emit (events.js:375:28)
at processIncomingData (/Users/simonegentili/Development/github.com/sensorario/youtube.poliglotta/node_modules/mongodb/lib/cmap/message_stream.js:125:16)
at MessageStream._write (/Users/simonegentili/Development/github.com/sensorario/youtube.poliglotta/node_modules/mongodb/lib/cmap/message_stream.js:33:9)
at writeOrBuffer (internal/streams/writable.js:358:12)
at MessageStream.Writable.write (internal/streams/writable.js:303:10)
at Socket.ondata (internal/streams/readable.js:726:22)
at Socket.emit (events.js:375:28)
at addChunk (internal/streams/readable.js:290:12)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:86146) 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: 1)
(node:86146) [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.
Why "Authentication failed"?

You need to:
update fastify mongo to v6 that supports fastify v4
The GET returns a cursor so change it to fastify.mongo.db.collection('books').find().toArray()
To get back the inserted id you need to change from inserted to insertedId
to set the MongoDB password duplicated question or you need to set the database property - code below updated:
note the plugin configuration
note the usage fastify.mongo.db.collection
Quick and dirty copy-paste:
const fastify = require('fastify')({ logger: !true })
fastify.register(require('#fastify/mongodb'), {
forceClose: true,
url: 'mongodb://root:example#localhost:27017',
database: 'library'
})
fastify.get('/books', async (request, reply) => {
const books = await fastify.mongo.db.collection('books').find().toArray()
reply.send(books)
})
fastify.post('/books', async (request, reply) => {
const result = await fastify
.mongo.db
.collection('books')
.insertOne(request.body)
reply.send({
message: 'book added',
id: result.insertedId
})
})
async function start () {
const done = await fastify.inject({
method: 'POST',
url: '/books',
body: { asd: 'foo' }
})
console.log(done.json())
const res = await fastify.inject('/books')
console.log(res.json())
fastify.close()
}
start()

Related

error in depolying contract >> Error: could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.7.2)

im trying the depoy my contract using npx hardhat run scripts/deploy.js --network goerli and i keep geeting the above error
//this is the error
omota#DESKTOP-3T9OR5N MINGW32 ~/web3-projects/tinder-blockchain/smart-contract (main)
$ npx hardhat run scripts/deploy.js --network goerli
Compiled 1 Solidity file successfully
error in depolying contract >> Error: could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.7.2)
at Logger.makeError (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\logger\src.ts\index.ts:269:28)
at Logger.throwError (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\logger\src.ts\index.ts:281:20)
at EthersProviderWrapper.<anonymous> (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\providers\src.ts\json-rpc-provider.ts:483:23)
at step (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\providers\lib\json-rpc-provider.js:48:23)
at Object.throw (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\providers\lib\json-rpc-provider.js:29:53)
at rejected (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\providers\lib\json-rpc-provider.js:21:65)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
reason: 'could not detect network',
code: 'NETWORK_ERROR',
event: 'noNetwork'
}
//here is my depoy.js file
const { ethers } = require('hardhat')
const main = async () => {
const tinderFactory = await ethers.getContractFactory('TinderERC721')
const tinderContract = await tinderFactory.deploy()
console.log('TINDER CONTRACT ADDRESS:', tinderContract.address)
};
main()
.then(() => process.exit(0))
.catch(error => {
console.log('error in depolying contract >>', error);
process.exit(1);
})
//here is my hardhat-config.js
require("#nomicfoundation/hardhat-toolbox");
require('dotenv').config({path: '.env'})
const ALCHEMY_API_URL = process.env.ALCHEMY_API_URL
const GOERLI_PRIVATE_KEY = process.env.GOERLI_PRIVATE_KEY
/** #type import('hardhat/config').HardhatUserConfig */
module.exports = {
defaultNetwork: 'goerli',
networks: {
goerli: {
url: ALCHEMY_API_URL,
accounts: [`0x${GOERLI_PRIVATE_KEY}`],
},
},
solidity: '0.8.17',
}
any help will be appreciated
i have done anything i can but still the same
I had the same error. Since you are using .env to store the private keys, if the value is being stored as:
"https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}" within the .env file itself, change it to the full link instead:
"https://eth-goerli.alchemyapi.io/v2/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
I was also getting a "private key too long" error as well because of using semi-colons to separate statements within the .env file... Hope this helps!
Maybe you have some problems with the ALCHEMY_API_URL. It should be in the form:
https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}
Or for sure, you can use public RPC nodes:
https://goerli.infura.io/v3/ //default on metamask
https://rpc.ankr.com/eth_goerli //I tried and it worked
https://eth-goerli.public.blastapi.io
https://rpc.goerli.mudit.blog

Unhandled promise rejection. This error originated either by throwing inside of an async function

i want to send the updatedUser informations plus an image file in the response but I get this kind of error: " 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: 1)
(node:69044) [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.".i googled this error but nothing helpful, so this is my code :
userRouter.post("/upload/:id",async(req, res)=> {
const user_id = req.params.id;
const pp = req.files.productImage;
const {data} = pp;
const namePp = uuidv4() + '.' + pp.name.split('.').pop();
pp.mv("./picturesProfile/" + namePp);
const updatedUser = await User.findByIdAndUpdate(user_id, {new: true},{image: namePp}, function (err, docs) {
if(err) {
console.log(err)
} else {
return docs
}
})
console.log(updatedUser)
res.send({updatedUser,pp});
})
This one will work you!
const doc = await User.findByIdAndUpdate(user_id,
{ $set: { "image": namePp }},
{
new: true,
runValidators : true
});

Mongoose Connection Error in Stackblitz - Mean app

I am trying to create a mean app. I am receiving errors while connecting mean app with MongoDb using mongoose. I am using "express": "^4.17.1", and "mongoose": "^6.0.7".
const mongoose = require('mongoose');
// Connecting to MongoDb
mongoose.connect(
'mongodb+srv://MongoDb:<password>#cluster0.xfdie.mongodb.net/myFirstDatabase?retryWrites=true&w=majority',
{
useNewUrlParser: true,
useUnifiedTopology: true,
}
);
// On Connection
mongoose.connection.on('connected', () => {
console.log('Connected to MongoDb');
});
mongoose.connection.on('error', (err) => {
if (err) {
console.log('Error in MongoDb Connection' + err);
}
});
It's working fine with the localhost but I am receiving the following error in Stackblitz.
Error in MongoDb ConnectionTypeError: this._handle[e] is not a function
(node:13) UnhandledPromiseRejectionWarning: TypeError: this._handle[e] is not a function
at Resolver.querySrv [as resolveSrv] (https://file-sharing-portal.jw.staticblitz.com/blitz.fa2fa735bbb029186c23972eb56445ed5c5fdef5.js:6:585119)
at Object.resolveSRVRecord (/home/projects/file-sharing-portal/node_modules/mongodb/lib/connection_string.js:55:9)
at Object.connect (/home/projects/file-sharing-portal/node_modules/mongodb/lib/operations/connect.js:41:36)
at eval (/home/projects/file-sharing-portal/node_modules/mongodb/lib/mongo_client.js:127:23)
at Object.maybePromise (/home/projects/file-sharing-portal/node_modules/mongodb/lib/utils.js:518:5)
at MongoClient.connect (/home/projects/file-sharing-portal/node_modules/mongodb/lib/mongo_client.js:126:24)
at eval (/home/projects/file-sharing-portal/node_modules/mongoose/lib/connection.js:785:12)
at new Promise (<anonymous>)
at NativeConnection.Connection.openUri (/home/projects/file-sharing-portal/node_modules/mongoose/lib/connection.js:776:19)
at eval (/home/projects/file-sharing-portal/node_modules/mongoose/lib/index.js:328:10)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:13) 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: 1)
(node:13) [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.
Please assist.
I asked for help in stackblitz-help channel in discord for the same and was informed that Mongoose isn't supported yet : https://github.com/stackblitz/core/issues/251
const mongoose = require('mongoose');
const app = express();
mongoose.Promise = global.Promise;
mongoose.connect("CONNECTION_STRING", "OPTIONS", (error) => {
if (error)
console.log("Connection error - ", error);
else
console.log("MongoDB connection established");
});
let server = http.createServer(app);
server.setTimeout(500000);
server.listen(3000);
try with above code snippets

How to use Mongoose to connect mongo-atlas db?

I'm following this tutorial to setup the mongo atlas db.
https://developerhandbook.com/mongodb/connect-mongo-atlas-mongoose/
But on the setup of connection, I got error like
(node:60566) UnhandledPromiseRejectionWarning: MongoError: user is not allowed to do action [find] on [admin.sample_airbnb]
at queryCallback (/Users/jay.lin/dev/graphql-playlist/server/node_modules/mongodb-core/lib/cursor.js:223:25)
at /Users/jay.lin/dev/graphql-playlist/server/node_modules/mongodb-core/lib/connection/pool.js:541:18
at process._tickCallback (internal/process/next_tick.js:61:11)
(node:60566) 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(). (rejection id: 1)
(node:60566) [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.
It seems atlas db is using "admin" collection by default, how can I change it to "sample_airbnb" collection?
const connector = mongoose.connect(
'mongodb+srv://test:<password>#cluster0-ppeaz.mongodb.net/a?retryWrites=true&w=majority'
)
.then(() => {
// connector.useDb('sample_airbnb?');
const Listing = mongoose.model(
'listingsAndReviews',
new mongoose.Schema({
name: String,
summary: String,
}),
'sample_airbnb'
);
Listing.findOne({}).then((r) => {
console.log(r);
})
})
(node:60566) You need to add "admin permission"s to be able to query the db. This will be under "security" tab then "Database Access". "Add new user" button (which is then used in your connection string).
".mongodb.net/a?" needs to be ".mongodb.net/sample_airbnb?"
(node:60566) Use try catch e.g.
const connector = mongoose.connect(
'mongodb+srv://test:<password>#cluster0-ppeaz.mongodb.net/sample_airbnb?retryWrites=true&w=majority'
)
.then(() => {
// connector.useDb('sample_airbnb?');
const Listing = mongoose.model(
'listingsAndReviews',
new mongoose.Schema({
name: String,
summary: String,
}),
'sample_airbnb'
);
try {
const listings = await Listing.findOne({});
res.json(listings);
} catch (err) {
res.json({ message: err });
}
});
});

Mongodb Atlas Express.js Error: getaddrinfo ENOTFOUND

I want to connect my express app to my mongoDb Atlas cluster.I'm from Iran, and cloud databases are sanctioned for us. I used VPN to bypass it in order to be able to practice.
Is there some coding mistake that I've done or is it because of using VPN?
The error:
(node:9008) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
connected
events.js:174
throw er; // Unhandled 'error' event
^
Error: getaddrinfo ENOTFOUND
is listening...
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)
Emitted 'error' event at:
at GetAddrInfoReqWrap.doListen [as callback] (net.js:1448:12)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:17)
[nodemon] app crashed - waiting for file changes before starting...
And the code:
database.js
----------------
const mongoDb = require('mongodb');
const MongoClient = mongoDb.MongoClient;
let _db;
const mongoConnect = callback => {
MongoClient.connect(
'mongodb+srv://<someUser>:<somePassword>#<someCluster>-zh1eb.mongodb.net/test?retryWrites=true'
)
.then(client => {
console.log('\nconnected\n');
_db = client.db();
callback();
})
.catch(err => {
console.log('\nerror\n', err);
throw err;
});
};
const getDb = () => {
if (_db) {
return _db;
}
throw 'NO DATABASE FOUND';
};
exports.mongoConnect = mongoConnect;
exports.getDb = getDb;
app.js
------------
...
const mongoConnect = require('./util/database').mongoConnect;
...
mongoConnect(() => {
app.listen(3000, '\nis listening...\n');
});
I found out what was the problem:
mongoConnect(() => {
app.listen(3000, '\nis listening...\n');
});
should actually be
mongoConnect(() => {
app.listen(3000, () => { console.log('\nis listening...\n');});
});
Silly me... :)
For those having such issue:
first check out whether the source of problem is your code or the connection to MongoDb.
That is instead of choosing "connect your application" select "connect with Mongodb Compass".
If the Mongodb Compass could connect and show your cluster, then definitely there is something wrong with your code, esp. how it's coded to connect.