Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated with 4.8.0 and 4.8.1 #4951

Closed
stevenelson94708 opened this issue Feb 2, 2017 · 37 comments
Labels
help wanted needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity

Comments

@stevenelson94708
Copy link

With mongoose versions 4.8.0 and 4.8.1 (node version is 6.9.5 and MongoDB version is 3.2.11) the following warning is generated the first time the save of a document occurs after starting the application (the warning does not appear when the same code is executed subsequent times after the first time while the application is still running, however, if the application is closed and restarted, then the first time a document save occurs after the application has been started the warning is generated):

DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html

This issue does not appear when using the exact same application code with mongoose versions 4.7.9 and earlier.

The code that sets up the mongoose connection is as follows:

`// Set up mongoose and DB connection
 var mongoose = require('mongoose');
 mongoose.Promise = require('bluebird');
 mongoose.connect('mongodb://localhost:27017/basedir', {server: { poolSize: 5 }});`
@stevenelson94708 stevenelson94708 changed the title DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated with 4.8.0 and 4.8.1 Feb 2, 2017
@sobafuchs
Copy link
Contributor

sobafuchs commented Feb 3, 2017

Can you paste the code that actually produces the error? That code won't because you haven't used a promise yet (unless you're saying that the connection snippet you posted does produce the warning?)

@sobafuchs sobafuchs added the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label Feb 3, 2017
@stevenelson94708
Copy link
Author

No the connection snippet does not produce the warning. The following newuser save snippet is the code that produces the warning, but only the first time that the code is executed after the application has been started (again, the warning does not occur in mongoose versions 4.7.9 and earlier):

 `                       var curDate = new Date();

                         var newuser = new user(
                         {                             
                                "userName": userName,
                                "hashed_password": hashed_password,
                                "emailReg": false,
                                "email": "~",
                                "firstName": "",
                                "lastName": "",
                                "address.streetAddress": "",
                                "address.city": "",
                                "address.state": "",
                                "address.postalCode": "",
                                "phoneNumbers": [],
                                "accessLevel": 2,
                                "active": true,
                                "trialStartDate": curDate,
                                "maxStorageByteLimit": constants.maxStorageBytesPerUser,
                                "signUpDate": curDate,
                                "passwordResetDate": curDate,
                                "salt": temp,
                                "storageBytesUsed": 0
                            });

                        if (phoneNumberValid != false)
                        {
                            newuser.phoneNumbers.push({
                                "type": "mobile",
                                "number": contactPhoneNumber,
                                "primary": true
                            });
                        }

                        wlogger.crit("Create new user by UserName: " + userName);

                        newuser.save(function (err)
                        {
                            if (err)
                            {
                                wlogger.error(err + " - when saving user "
                                    + " creation by UserName: " + userName);
                                callback({
                                    "response": false,
                                    "res": "User creation failed. "
                                    + " Please try again or contact us at support@nuubis.com"
                                });
                            }
                            else
                            {
                                wlogger.crit("Saved new user info for UserName: "
                                    + userName);

                                return callback({
                                        "response": true,
                                        "res": "Created user by User Name " + userName,
                                        "user_id": newuser._id,
                                        "last_modified_date": curDate
                                });
                            }
                        })`

The user schema is as follows:

`var userSchema = mongoose.Schema({ 
token : String,
email: String,
userName: String,
deviceId: String,
devicePhoneNumber: String, 
hashed_password: String, 
hashed_admin_code: String,
maxStorageByteLimit: { type: Number, default: 1073741824 },
accessLevel: { type: Number, default: 2 },
lastAccessType: Number,
storageBytesUsed: { type: Number, default: 0 },
totalStorageBytesUsed: { type: Number, default: 0 },
deletedStorageBytesUsed: { type: Number, default: 0 },
salt : String,
salt1 : String,
temp_str: String,
syncInProcess: { type: Boolean, default: false },
syncStartDate: { type: Date, default: Date.now },
syncVersion : { type: Number, default: 0 },
active: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
emailReg: { type: Boolean, default: false },
regPending: { type: Boolean, default: false },
emailChangePending: { type: Boolean, default: false },
regCodeSendCount: { type: Number, default: 0 },
trialStartDate: Date,
signUpDate: Date,
passwordResetDate: Date,
lastLoginDate: Date,
lastModifiedDate: Date,
curLoginDate: Date,
apnDeviceTokens: [ String ],
curSessionIds: [ String ],
curIpAddr: { ipType: String, 
    upper64: Schema.Types.Long,
    lower64: Schema.Types.Long },
firstName: String,
lastName: String,
address: { streetAddress: String,
    city: String,
    state: String, postalCode: String },
phoneNumbers: [ phoneNumbersSchema ],
categories: [ categoriesSchema ],
providerCustomers: [ customerSchema ],
serviceProviders: [ providerSchema ],
ipAddrs: [ ipAddrSchema ],
recentUploads: [ recentUploadSchema ],
recentUploadsGizmo: [ recentUploadSchema ],
recentUploadsLife: [ recentUploadSchema ],
recentUploadsVehicle: [ recentUploadSchema ],
recentUploadsMisc: [ recentUploadSchema ],
recentViews: [ recentViewsSchema ],
recentAdds: [ recentAddsSchema ],
recentAddedFiles: [ recentAddedFilesSchema ],
locations: [ locationSchema ],
inMessages: [ inMessageSchema],
outMessages: [ outMessageSchema ]
  });`

@bricss
Copy link

bricss commented Feb 5, 2017

I can confirm the same problem with mongoose v4.8.1 & node.js v7.5.0.

mongoose.Promise = global.Promise;
mongoose.connect(db.mongodb.uri, db.mongodb.options);
DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html

@sobafuchs
Copy link
Contributor

@stevenelson74708 thanks for the snippet, but the schema itself probably isn't the problem. What i'm looking for more is how the schema gets imported and used relative to when the connection is opened / the mongoose Promise constructor is set.

@stevenelson94708
Copy link
Author

The schema is exported from the schema file where it is declared as follows:

`module.exports = mongoose.model('users', userSchema);   `

and the schema is imported into the file it is used where newuser.save is called as follows:

`var user = require('config/models/users');`

The connect snippet (where the connection is open and the mongoose Promise constructor is set) shown in my first post occurs in the app.js file which runs at initialization during application startup.

The newuser.save snippet shown in my second post gets executed from the file where the user schema is imported and the newuser.save gets executed when a user interacts with the application and causes a specific route to be executed, which is well after application initialization has been completed.

The warning occurs only the first time the newuser.save code executes after application startup even though the same newuser.save code is executed many times after startup, and the warning does not appear to occur with mongoose versions 4.7.9 and earlier.

@sobafuchs
Copy link
Contributor

@stevenelson74708 i'm going to need to see all of the components that play a role in your app's startup. A lot of people have opened issues recently regarding this, and every single one has stemmed from improperly setting the promise constructor, so my guess is you're doing something wrong in the order in which you set mongoose.Promise.

Is there any way that I can see your code?

@stevenelson94708
Copy link
Author

Below is all the code (in exact order) in the app.js initialization that is related to mongoose configuration, including setting mongoose.Promise. The warning does not occur when the initialization code executes. The warning only occurs the first time the newuser.save code (show in my previous post) executes after the application has been initialized. There are findOneAndUpdate calls that execute before the save that don't cause the warning, so it appears that it's only the save functionality that causes the warning.

The mongoose configuration is one of the first things that occurs in the initialization. Should the mongoose configuration occur later in the initialization such as after the createServer functionality?

Again, the warning does not appear to occur in mongoose versions 4.7.9 and earlier:

`// Set up mongoose and DB connection
var mongoose = require('mongoose');

mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost:27017/basedir', {server: { poolSize: 5 }});
var conn = mongoose.connection;

conn.once('open', function ()
{
    wlogger.info("Mongoose connection opened on process " + process.pid);
});`

@sobafuchs
Copy link
Contributor

sobafuchs commented Feb 7, 2017

No, the configuration can come first. Is this file the entry point for your app or is there a file that precedes this?

@stevenelson94708
Copy link
Author

The app.js file is the entry point for the application. The application can be invoked by typing node app.js at the command line.

@vdjurdjevic
Copy link

vdjurdjevic commented Feb 9, 2017

I have same problem with mongoose 4.8.1 and node 7.5.0. I am also using Typescript and trying to plug Bluebird for promises. I found out that warning disappears if i add this code:

`import * as mongoose from 'mongoose';
 import * as bluebird from 'bluebird';

 (<any>mongoose).Promise = bluebird;`

in EVERY file that imports something from 'mongoose'. So i need to do that in every model file (file where i define my schema) instead in entry point file only.

@vkarpov15
Copy link
Collaborator

// Set up mongoose and DB connection
var mongoose = require('mongoose');

mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost:27017/basedir', {server: { poolSize: 5 }});
var conn = mongoose.connection;

conn.once('open', function ()
{
    console.log('test');
});

Doesn't print this warning, so there's something else.

@vladimirdjurdjevic this means that somewhere you're using a mongoose async op before setting the promise lib. I don't use TS so I don't know if that has anything to do with it.

@stevenelson94708
Copy link
Author

I set the promise lib as shown above in the app.js file which is the entry point of the application, and then when the first newuser.save is performed (long after the promise lib has been set) as shown above the warning occurs. The newuser.save is the first mongoose async op that occurs, but it occurs well after the promise is lib is set for the connection.

Does the promise lib have to be set in each file that accesses mongoose async functions as opposed to setting the promise lib only once when the mongoose connection is configured?

@ivorscott
Copy link

ivorscott commented Feb 12, 2017

@stevenelson74708 I had the same problem. I thought I resolved it with: mongoose.Promise = global.Promise in the entry point of the application. Looks like you do need it in every file that accesses mongoose promises. Pretty annoying. Just set the mongoose configuration in a separate file, export it and import it wherever needed.

@mcfarljw
Copy link

mcfarljw commented Feb 12, 2017

I also recently noticed that I'm getting this warning, although I've set the promise in my app.js file. I've tried using both native and bluebird with the same results.

// FILE: app.js
import bluebird from 'bluebird';
import mongoose from 'mongoose';

// use bluebird as default promise library
mongoose.Promise = bluebird;

I'm importing mongoose into a few of my models and using them in schema methods. I've solved the problem by setting the promise library in ever file that imports mongoose on its own (see the TODO in the snippet below). I don't recall seeing the warning a few months ago given a similar code structure.

// FILE: SessionModel.js
import bluebird from 'bluebird';
import mongoose from 'mongoose';

// TODO: remove this redundant bit of code
// use bluebird as default promise library
mongoose.Promise = bluebird;

SessionSchema.methods.getUser = function(callback) {
  return mongoose.model('User').findById(this.user, callback);
};

@ivorscott
Copy link

ivorscott commented Feb 12, 2017

@mcfarljw You are better off doing something like this:

// config.js
const bluebird = require('bluebird');
const mongoose = require('mongoose');
mongoose.Promise = bluebird;
mongoose.connect('mongodb://localhost:27017/myApp)
module.exports = { mongoose }
// SessionModel.js
const { mongoose } = require('./config')

SessionSchema.methods.getUser = function(callback) {
  return mongoose.model('User').findById(this.user, callback);
};

That way you won't have to write "mongoose.Promise = bluebird" numerous times :)

@benfletcher
Copy link

In my situation, was getting the deprecation warning when acting on sub-docs using .then() syntax, but not on parent docs. So the occasional warning made me think I had syntax problems with dealing with children docs, but it was in fact the lack of promise line in the model file as others have advised above.

@stevenelson94708
Copy link
Author

Yes, it appears that setting the mongoose.Promise in the schema files where mongoose.model is exported eliminates the warning in mongoose versions 4.8 and later.

@sobafuchs
Copy link
Contributor

Yeah passing around the mongoose singleton as your own mutated export would get around the issue, but it's admittedly a bit of a hack.

@stevenelson94708
Copy link
Author

At this point it's unclear to me as to exactly what the "proper" mongoose setup/configuration to avoid the warning is. Is this warning an issue with current mongoose versions or or is it an indication of an improper mongoose setup? Is there a recommended mongoose setup that will prevent the warning? Again, this warning only starting occurring with mongoose version 4.8.0.

@thomas-lee
Copy link

I have the same problem on setting the global mongoose.

I have traced down, it can set the bluebird properly down to promise_provider but when i tried to get back the promise, it will return the ES6 one.

@ghost
Copy link

ghost commented Feb 27, 2017

I just went through and added

mongoose.Promise = global.Promise

immediately following the require/import of mongoose in every source file that uses it, and although that's overkill, it took very little thinking and not very much time doing, and it did fix it completely. So, not really the biggest of deals.

It does challenge my admittedly limited knowledge of how require and import work. I was under the impression that no matter how many times you require something, you always get the same instance, so setting the promise once should be enough, you would think. So it's a bit counter-intuitive.

@stillesjo
Copy link

Hi
I have some example code that cause the problem

import mongoose from 'mongoose';

mongoose.Promise = Promise;

import Test from './test.model';

mongoose.connect(uri, options);
mongoose.connection.on('error', err => console.error(`MongoDB connection error: ${err}`));

Test.create({ name: 'Hi'})
  .then(() => Test.findOne({}))
  .then(res => res.save())
  .then(() => console.log('Done'));

(test.model is just a simple model with one field for name)

For some reason the problem first appears when doing res.save();. Without it everything works as usual.

I believe that this problem comes from babel changing the order when transpiling the code. When babel transpiles, it moves all the imports to the top. So when the test.model is imported in my example the Promise-library is still assigned to mpromise.

@JonathanVandal
Copy link

JonathanVandal commented Mar 1, 2017

I'm using Node.js 6.10.0 and Mongoose 4.8.5 and I got this problem to.

I save my user object :

var newUser = User({
    login       : 'john',
    password    : 'secret',
    firstname   : 'John',
    lastname    : 'Doe',
    avatar      : 'avatar.png'
});

newUser.save(function(err){
    if(err) throw err;

    console.log('User created !');
});

And I have the same error. I tried this way :

mongoose.Promise = require('bluebird');
mongoose.connect(conf.dbpath);

And this way :

mongoose.Promise = global.Promise;
mongoose.connect(conf.dbpath);

But I have again the deprecated warning. How can I fix this ?

@bricss
Copy link

bricss commented Mar 1, 2017

Howto Fix Deprecation Warning:

var mongoose = require('mongoose');

mongoose.Promise = global.Promise;
var schema = new mongoose.Schema({
 // definition
}, {
 // options
});

module.exports = mongoose.model('foobar', schema);

@JonathanVandal
Copy link

JonathanVandal commented Mar 1, 2017

Yeah it works if I put this in my model. So we have to init mongoose.Promise inside each model.

@mcfarljw
Copy link

mcfarljw commented Mar 1, 2017

I think @stevenelson74708 has an excellent point when saying At this point it's unclear to me as to exactly what the "proper" mongoose setup/configuration to avoid the warning is.

Yes, a fix would be to go back through all mongoose model files and add mongoose.Promise = global.Promise after the import, but since this issue has only cropped up recently it'd be nice to get a more concrete answer as to the intentions or causes behind it. I'm uncertain at this point whether it's an issue caused by mongoose, babel or a combination of the two.

@vkarpov15
Copy link
Collaborator

Likely a dupe of #5030. Try upgrading to >= 4.9.1.

@Gascon95
Copy link

Gascon95 commented Apr 6, 2017

For the record, @bricss solution worked pretty well for me :)

@ghost
Copy link

ghost commented Apr 11, 2017

At first the solution comes from @steve-p-com. Not from @bricss.
@vkarpov15 same warning with 4.9.3.
@stillesjo it's nothing with babel. The warning occurres also on nativ without Babel on Node 7.8.0.

@bricss
Copy link

bricss commented Apr 11, 2017

I don't have any warnings since version 4.9.3 🌷

@lesterzone
Copy link

Even when we set mongoose.Promise = global.Promise; on every model I think it's not an ideal fix right ? Why not using global.Promise as default and let users change if they want to ?

Unit testing my models. I have to include it so we don't see the warning when running tests locally or on CI.
I'm using "mongoose": "4.10.4" with node v7.10.0

@pitops
Copy link

pitops commented Aug 6, 2017

@lesterzone

Just to add to this a DRY solution, set it up where you initialise the connection with teh database instead of setting inside each model.

const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://...');

seems to work

@ghost
Copy link

ghost commented Aug 8, 2017

That won't necessarily work for everyone though. It depends on your code structure. If for example the file with the connection code requires models from separate source files, the way require works means that those source files will get loaded before the global promise has been set in the file containing the connection code. Those models will continue to use the default value for the promise. The safe route is simply to set the global promise in every source file that requires mongoose.

@MarJaysonSanAgustin
Copy link

MarJaysonSanAgustin commented Aug 17, 2017

this works for me

import mongoose from 'mongoose';
import config from './config';
import bluebird from 'bluebird';

export default callback => {
    mongoose.Promise = bluebird;
    //connect to the database from the instance of the database in config file
    let db = mongoose.connect(config.mongoUrl, {useMongoClient: true});
    callback(db);
}

@pleasezoomout
Copy link

pleasezoomout commented Aug 23, 2017

That's that way I'm doing it.

var colors = require('colors');
var mongo = require('mongodb');
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');

var db = mongoose.connection;

mongoose.connect('mongodb://localhost:27017/db', { useMongoClient: true })
.then(function(){
  console.log(" Connected to dbName ".green);

}).catch(err => console.error(err));

@Gilbert136
Copy link

You have to use .create function that comes with mongoose rather than .save,
I changed mine and it fixes the problem

@markonyango
Copy link

I am on 4.13.9 and this still exists. @Gilbert136 solution fixes this, strikes me as odd though. .create calls .save, so how come there is no deprecation warning then?

@Automattic Automattic locked as resolved and limited conversation to collaborators Jan 9, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity
Projects
None yet
Development

No branches or pull requests