I'm just trying to implement the simple example gived in the project presentation.
The only modification I made was to change Image by File (because i want store pdf files)
All work ! but I've got an error message in server console which look like that :
I20161204-23:39:41.309(1)? Exception in callback of async function: Error: object [{"_bsontype":"ObjectID","id":"WESaDDklWQql0sb0"}] is not a valid ObjectId
I20161204-23:39:41.310(1)? at Object.Future.wait (/home/joel/.meteor/packages/meteor-tool/.1.4.2_3.l0lhon++os.linux.x86_64+web.browser+web.cordova/mt-os.linux.x86_64/dev_bundle/server-lib/node_modules/fibers/future.js:446:16)
I20161204-23:39:41.312(1)? at MongoConnection.<anonymous> (packages/meteor.js:213:24)
I20161204-23:39:41.313(1)? at MongoConnection.meteorInstall.node_modules.meteor.mongo.mongo_driver.js._.each.MongoConnection.(anonymous function) [as update] (packages/mongo/mongo_driver.js:774:49)
I20161204-23:39:41.313(1)? at [object Object].update (packages/mongo/collection.js:589:29)
I20161204-23:39:41.314(1)? at collections/upload-cv.js:37:25
I20161204-23:39:41.314(1)? at runWithEnvironment (packages/meteor.js:1176:24)
I20161204-23:39:41.315(1)? - - - - -
I20161204-23:39:41.316(1)? at serializeObjectId (/home/joel/.meteor/packages/npm-mongo/.2.2.11_2.1r0wpm6++os+web.browser+web.cordova/npm/node_modules/bson/lib/bson/parser/serializer.js:255:11)
I20161204-23:39:41.317(1)? at serializeInto (/home/joel/.meteor/packages/npm-mongo/.2.2.11_2.1r0wpm6++os+web.browser+web.cordova/npm/node_modules/bson/lib/bson/parser/serializer.js:760:17)
I20161204-23:39:41.319(1)? at serializeObject (/home/joel/.meteor/packages/npm-mongo/.2.2.11_2.1r0wpm6++os+web.browser+web.cordova/npm/node_modules/bson/lib/bson/parser/serializer.js:300:18)
I20161204-23:39:41.321(1)? at serializeInto (/home/joel/.meteor/packages/npm-mongo/.2.2.11_2.1r0wpm6++os+web.browser+web.cordova/npm/node_modules/bson/lib/bson/parser/serializer.js:608:17)
I20161204-23:39:41.323(1)? at serializeObject (/home/joel/.meteor/packages/npm-mongo/.2.2.11_2.1r0wpm6++os+web.browser+web.cordova/npm/node_modules/bson/lib/bson/parser/serializer.js:300:18)
I20161204-23:39:41.324(1)? at serializeInto (/home/joel/.meteor/packages/npm-mongo/.2.2.11_2.1r0wpm6++os+web.browser+web.cordova/npm/node_modules/bson/lib/bson/parser/serializer.js:766:17)
I20161204-23:39:41.325(1)? at [object Object].serialize (/home/joel/.meteor/packages/npm-mongo/.2.2.11_2.1r0wpm6++os+web.browser+web.cordova/npm/node_modules/bson/lib/bson/bson.js:49:27)
I20161204-23:39:41.325(1)? at [object Object].Query.toBin (/home/joel/.meteor/packages/npm-mongo/.2.2.11_2.1r0wpm6++os+web.browser+web.cordova/npm/node_modules/mongodb-core/lib/connection/commands.js:143:25)
I20161204-23:39:41.326(1)? at [object Object].Pool.write (/home/joel/.meteor/packages/npm-mongo/.2.2.11_2.1r0wpm6++os+web.browser+web.cordova/npm/node_modules/mongodb-core/lib/connection/pool.js:920:23)
I20161204-23:39:41.327(1)? at executeWrite (/home/joel/.meteor/packages/npm-mongo/.2.2.11_2.1r0wpm6++os+web.browser+web.cordova/npm/node_modules/mongodb-core/lib/wireprotocol/3_2_support.js:78:10)
The bug come from these lines :
writeStream.on('close', Meteor.bindEnvironment(file => {
const property = `versions.${versionName}.meta.gridFsFileId`;
// If we store the ObjectID itself, Meteor (EJSON?) seems to convert it to a
// LocalCollection.ObjectID, which GFS doesn't understand.
this.collection.update(file._id, { $set: { [property]: file._id.toString() } });
this.unlink(this.collection.findOne(file._id), versionName); // Unlink files from FS
}));
I'm running on last meteor update Meteor 1.4.2.3 and ostrio:[email protected] ...
Anyone have an idea ?
Thank you in advance
Hi @jalaux ,
This one looks new to me. As far as I see it's coming from mongo_driver.js.
What MongoDB version you're running on? It's build-in into Meteor or separately running instance?
The bug come from these lines :
Which file?
Hi @dr-dimitru ,
I'm using the mongo buid-in into Meteor ([email protected]).
The lines are extracted from example in Meteor-Files/docs/gridfs-integration.md
@jalaux
Looks like image._id id not a String but an ObjectId here:
this.collection.update(image._id, { $set: { [property]: file._id.toString() } });
// ^
Could you try to convert it to String or compose new ObjectId()?
Hello,
I used file._id.toString() but that did not working ...
so I commented folowing lines
this.collection.update(file._id, { $set: { [property]: file._id.toString() } });
this.unlink(this.collection.findOne(file._id), versionName); // Unlink files from FS
and that's working ...
but i'm not sure that it's a good solution.
Those lines set necessary fields to serve file from GridFS, and removes file from FS
Could you console.log(file._id), please?
and that's working ...
but i'm not sure that it's a good solution.
File served from FS, not GridFS
One more thing - you're using ES6 "fat arrow" functions, which drops necessary for this event context. This may be the source of issue.
UPDATE:
I see same style use in a docs, but you should try to switch to classic function() {}
I uncommented the two lines. first, for id console log :
#### file._id聽####
5864c649af05b31847bc5805
#### file._id.toString()聽####
5864c649af05b31847bc5805
It's the same in console log however the followning just file._id.toString() seems working (file._id聽doesnt) ...
For 'fat arrow', I already tried to suppress them... but in this case I'm got an error on this.collection which is not defined ... ??
@jalaux ,
Okay, still weird.
What your current status, error and code?
Current status is an error on unlink ... the error message in server console is :
I20170102-11:26:25.161(1)? Exception in callback of async function: TypeError: Cannot read property 'versions' of undefined
I20170102-11:26:25.162(1)? at FilesCollection.module.runModuleSetters.FilesCollection.unlink (/home/joel/project/c10po/beta/.meteor/local/build/programs/server/packages/ostrio_files.js:2910:26)
I20170102-11:26:25.162(1)? at collections/upload-cv.js:67:22
I20170102-11:26:25.163(1)? at runWithEnvironment (packages/meteor.js:1176:24)
This erro come from this line this.unlink(this.collection.findOne(file._id.toString()), versionName);
Below the entire code :
import { Meteor} from 'meteor/meteor';
import { FilesCollection} from 'meteor/ostrio:files';
import Grid from 'gridfs-stream';
import { MongoInternals } from 'meteor/mongo';
import fs from 'fs';
let gfs;
if (Meteor.isServer) {
gfs = Grid( MongoInternals.defaultRemoteCollectionDriver().mongo.db, MongoInternals.NpmModule );
}
export const CV_files = new FilesCollection({
collectionName: 'CV_files',
storagePath: 'assets/app/uploads/CV_files',
allowClientCode: false,
debug: false, //Meteor.isServer && process.env.NODE_ENV === 'development',
onBeforeUpload(file) {
if (file.size <= 10485760 && /pdf/i.test(file.extension)) return true;
return 'Merci de d茅poser des fichiers PDF, avec une taille inf茅rieure ou 茅gale 脿 10MB';
},
onAfterUpload(file) {
// Move file to GridFS
Object.keys(file.versions).forEach(versionName => {
const metadata = {
versionName,
fileId: file._id,
storedAt: new Date(),
dispoId : file.meta.dispoId,
}; // Optional
const writeStream = gfs.createWriteStream({
filename: file.name,
metadata
});
fs.createReadStream(file.versions[versionName].path).pipe(writeStream);
writeStream.on('close', Meteor.bindEnvironment(file => {
const property = `versions.${versionName}.meta.gridFsFileId`;
// If we store the ObjectID itself, Meteor (EJSON?) seems to convert it to a
// LocalCollection.ObjectID, which GFS doesn't understand.
this.collection.update(file._id.toString(), {
$set: {
[property]: file._id.toString()
}
});
console.log("UNLINK : ");
this.unlink(this.collection.findOne(file._id.toString()), versionName); // Unlink file by version from FS
}));
});
},
interceptDownload(http, file, versionName) {
const _id = (file.versions[versionName].meta || {}).gridFsFileId;
if (_id) {
const readStream = gfs.createReadStream({
_id
});
readStream.on('error', err => {
throw err;
});
readStream.pipe(http.response);
}
return Boolean(_id); // Serve file from either GridFS or FS if it wasn't uploaded yet
},
onAfterRemove(CV_files) {
// Remove corresponding file from GridFS
CV_files.forEach(file => {
Object.keys(file.versions).forEach(versionName => {
const _id = (file.versions[versionName].meta || {}).gridFsFileId;
if (_id) gfs.remove({
_id
}, err => {
if (err) throw err;
});
});
});
}
});
@jalaux well I went trough this conversation - lots of stuff is broken.
Could we make sure this solution works for you without 3rd party storage, GridFS in your case, in first place. Then we will integrate GridFS. What do you think?
of course as you want ...
How can I do it?
for information... I've tried to change the unlink operation from
this.unlink(this.collection.findOne(file._id.toString()), versionName); // Unlink file by version from FS
to
this.unlink(this.collection.find(file._id), versionName); // Unlink file by version from FS
I don't have an error message anymore...
However, when I restart the server, I couldn't access to files
How can I do it?
Just comment out onAfterUpload and interceptDownload
.unlink() is not playing a role now, it just removes files from FS after successful transfer to 3rd party storage
Hello @jalaux ,
Any news on your end?
Hello @dr-dimitru ,
I made the test. I created a test project or I removed expenses that could have caused problems
https://github.com/jalaux/Test-Meteor-Files
Without 3rd party storage, all seems correct...
@jalaux ,
The issue is in the code, you adopted from GFS integration example: the file argument of onAfterUpload, got overridden by file argument in Meteor.bindEnvironment callback. Originally there was two different (image and file) variables used in this.collection.update call.
Correct, this should work if you change this code to:
onAfterUpload(file) {
// Move file to GridFS
// ...
writeStream.on('close', Meteor.bindEnvironment(uploadedFile => {
const property = `versions.${versionName}.meta.gridFsFileId`;
// If we store the ObjectID itself, Meteor (EJSON?) seems to convert it to a
// LocalCollection.ObjectID, which GFS doesn't understand.
this.collection.update(file._id.toString(), {
$set: {
[property]: file._id.toString()
}
});
console.log("UNLINK : ");
this.unlink(this.collection.findOne(file._id.toString()), versionName); // Unlink file by version from FS
}));
});
},
Just got the same error fixed by this way.
Feel free to reopen it in case if the issue still persists on your end.
just passing by from year 2018, got the same problem @jankapunkt nailed it. Thank you so much for the fix and the library itself.
Most helpful comment
Correct, this should work if you change this code to:
Just got the same error fixed by this way.