How can i use MongoDB with Cloud Functions for Firebase? - mongodb

I want to use Cloud Functions for Firebase and MongoDB. The problem is I don't know how to connect my Mongo database with Cloud Functions. My database is deployed at matlab.
I made this schema:
var mongoose = require('mongoose')
var Schema = mongoose.Schema
var patientSchema = new Schema({
name: {
type: String,
required : true,
},
disease:{
type: String,
required : true,
},
medication_provided: {
type: String,
required : true,
},
date : {
type : Date,
}
})
const patient = mongoose.model('patientInfo', patientSchema)
module.exports = patient
Then I require my schema in project index.js file, and export a function called getAllPatient.
const patient = require('../Patient')
const functions = require('firebase-functions');
const mongoose = require('mongoose')
mongoose.connect('mongodb://patient:patient123#ds139869.mlab.com:39869/patient',{useMongoClient: true})
exports.getAllPatient = functions.https.onRequest((request, response) => {
patient.find({}).then((data) => {
response.send(data)
})
})
but gives me an error that "Error: could not handle the request"

I was recently facing this type of error and found that firebase free plan doesn't allow the outbound connections from within the functions. If you need to call external http/tcp connections, you are required to be on the flame or blaze plan. see the screenshot attached below or see the section cloud functions -> outbound networking at this link Firebase Pricing

Try to design the cloud function in a similar way shown in a link below:-
https://github.com/firebase/functions-samples/blob/master/authorized-https-endpoint/functions/index.js
I've tried with mongoose long time back and it was working fine and but it's slow because for every new request it's going to open the mongoose connection and serve you the data.
Hope this helps!!

Related

mongoose use model/scheme for multiple databases and multiple collections

I am looking for a way to use 1 schema for multiple databases and collections. I have 3 different databases and each holds 3 to 4 collections, which use all the same schema. I started just duplicating the schema for each collection and database, but that will add up to the amount of work. then I tried to export a function that returns the schema with set parameter, but I think that creates a new connection each time I call the function and eventually I get error. I can not find how to solve my problem the right way. Please someone can help me out a little.
What I currently try to use.
import mongoose from 'mongoose';
import Config from '../components/config.js';
const {database, localDatabase} = Config();
export default function(dex, network){
const db = mongoose.createConnection(localDatabase);
const transactions = db.useDb(network); // each network gets its own database
const txSchema = new mongoose.Schema({
uniquePoint:{
type: String,
required: true,
index: true,
unique : true,
},
version:{
type: String,
required: true,
},
network:{
type: String,
required: true,
},
},{collection: dex}); // each dex gets own collection
return transactions.model('TX', txSchema);
}
But this seems to give error after a while "MongoNetworkError: connect EADDRNOTAVAIL"

Cannot overwrite mongoose model once compiled with Nextjs

Before you close this question, I have read several forums that have the same question as I have but my issue is way different. Even when Im not trying to do anything, even save a model, it still gives me an error of:
cannot overwrite "mongoose" model once compiled
I have a feeling there is something wrong with my schemas because when it was still simpler, it worked fine but as I tried to make it more complex it started to give me that error. Here is my mongoose code:
import mongoose from 'mongoose'
const flashcardItemSchema = new mongoose.Schema({
term: {
type:String,
required: true,
min:1
},
description: {
type:String,
required:true,
min:1
}
});
const FlashcardItem = mongoose.model("flashcardItem", flashcardItemSchema);
const flashcardSetSchema = new mongoose.Schema({
title: {
type: String,
min: 1,
},
flashcards:[flashcardItemSchema],
})
const FlashcardSet = mongoose.model('flashcardSet', flashcardSetSchema )
export {FlashcardItem, FlashcardSet}
I connect to my database when the server runs, so it doesn't disconnect from time to time.
UPDATE
I realized that I'm using nextjs builtin api, meaning the api directory is inside the page directory. I only get the error once the pages get recompiled.
So it turns out that the error came from nextjs trying to remake the model every render. There is an answer here: Mongoose/NextJS - Model is not defined / Cannot overwrite model once compiled
but I thought the code was too long and all that fixed mine was just a single line. When trying to save a model in nextjs, it should be written like this:
const modelName = mongoose.models.modelName || mongoose.model('modelName', flashcardSetSchema )

AccessDenied error in GraphQl API, can't figure it out

GraphQl PLayground Error screenshot (same error I get in the client)
Hello everyone, I am having a very frustrating problem on a small project i'm working on. I cannot delete items from my cart on the client because I get an accessDenied error. This website has no authentification, and it is not supposed to. I want everyone who is on the site to be able to add and delete cart items at will. I am using GraphQl, Keystone, and mongoDB, I have tried everything I can in the keystone.js database to allow access, I have the access field on all lists and set everything to true. I can delete CartItems just fine in the graphQl Playground, but not on the client or in the admin playground. If anyone can offer some help or advice it would be greatly appreciated, thanks!
Here is my keystone DB:
const { Keystone } = require('#keystonejs/keystone');
const { GraphQLApp } = require('#keystonejs/app-graphql');
const { AdminUIApp } = require('#keystonejs/app-admin-ui');
const { MongooseAdapter: Adapter } = require('#keystonejs/adapter-mongoose');
const FoodItem = require('./lists/FoodItem');
const Category = require('./lists/Category');
const Salad = require('./lists/Salad');
const Order = require('./lists/Order');
const saladCartItem = require('./lists/saladCartItem');
const foodCartItem = require('./lists/foodCartItem');
const Cart = require('./lists/Cart');
const PROJECT_NAME = 'ghost-grits';
const adapterConfig = { mongoUri: process.env.DATABASE_URL };
const keystone = new Keystone({
adapter: new Adapter(adapterConfig),
cookieSecret: process.env.COOKIE_SECRET,
defaultAccess: {
list: true,
field: true
}
});
keystone.createList('FoodItem', FoodItem)
keystone.createList('Category', Category)
keystone.createList('Salad', Salad)
keystone.createList('Order', Order)
keystone.createList('saladCartItem', saladCartItem)
keystone.createList('foodCartItem', foodCartItem)
keystone.createList('Cart', Cart)
module.exports = {
keystone,
apps: [new GraphQLApp({ isAccessAllowed: true }), new AdminUIApp({ name: PROJECT_NAME, enableDefaultRoute: true, isAccessAllowed: true })],
};
And here is the access field, I have put an identical one of these on all my lists:
const FoodItem = list({
access: {
read: true,
update: true,
delete: true,
create: true
},
This is known issue in keystone. When you have no item with that Item id, it will give you access denied error even if there is no access control setup.
check if your client app is sending correct variable to graphql. you can use chrome devtools and look for api calls. make sure the query is right and variable has correct data. You can also check by querying the item using that id and if that returns any result.

How to Connect/Query Mongoose to an existing Database

I am working on trying to connect a Node/Express server to an existing MongoDB Database/Collection. I have already successfully connected to the database. However, I am having a tremendously difficult time setting up my models/schema to query.
The MongoDB is MongoDB Atlas and has one collection with over 800,000 documents. The name of the single collection is "delitosCollection".
I have tried the following to with no success:
var CrimeData = mongoose.model('DelitosCollection', new Schema({}),'delitosCollection');
mongoose.connection.on('open', function(ref){
console.log("connected to the mongo server");
CrimeData.find({}, (err,results) => {
if(err){
console.log("ERROR")
throw err
}
console.log("results: ", results.length)
} )
});
I know the connection is working as I am receiving the console.log with no errors. However, results.length is returning 0 when it should be over 800,000. Have spent way too many hours on this.
Create an empty schema for each collection you want to use
and then create a model to be used in your project
the model take 3 parameter
1)name of the model
2)schema name
3)collection name ( from mongodb atlas)
like that
const mongoose = require('mongoose');
mongoose.connect('mongodb uri')
const userSchema = new mongoose.Schema({});
const User = mongoose.model('User', userSchema, 'user');
then you can use the model normally
User.find({})
connection to mongo db
// Connect to mongoDB
mongoose.connect('mongodb://localhost/[yourDbName]',{useNewUrlParser:true})
.then(function(){
console.log('mongoDB connected');
})
.catch(function(){
console.log('Error :');
})
after that you will have to create your schema and then only you can query the database
create your schema like this
// Crimes Schema
const CrimeDetailsSchema= new Schema({
first_name: {
type: String,
required: true
},
last_name: {
type: String,
required: true
},
email: {
type: String,
required: true
}
});
const Profile = module.exports = mongoose.model('delitosCollection', CrimeDetailsSchema, 'delitosCollection');
after that create your queries
you can get an idea about that in mongoose documentation here
You can refer to the answer given below, just pass an empty object in schema
like db.model('users', new Schema({}))

How to handle unique indexes with mongoose?

The FAQ section of Mongoose 5 explitily says:
The unique option for schemas is convenient for development and documentation, but mongoose is not an index management solution.
This statement threw me off as I'm relatively new to Mongoose library. I'm making a basic model for User and adding a couple of tests for validation. Specifically validate no duplicate users are there.
The schema is simple
const schema = new Schema({
email: { type: String, required: true, unique: true },
...
Needless to say, my test fail:
const userA = new User({ email: 'a#a.com' });
const dupUserA = new User({ email: 'a#a.com' });
const promiseChain = userA.save().then(() => dupUserA.save());
expect(promiseChain).to.be.rejected // using chai-as-promised here
.then(err => {
// assertions about error message
});
The test fails cause the promise fulfills, meaning the save was successful.
I don't quite understand what Mongoose team means. I realize these schema are no database "migrations", but since the only example there is in the docs is some callback to the 'index' event, I'm lost.
How should I handle unique index? Is there a solution not to do them directly to the MongoDB through shell? Something that can reside in the codebase, equivalent to migrations?