Has someone experience with storing uploaded files with meteor-files on google cloud? There are some errors I can’t solve on my own.
I’m using windows.
I tried following the guide on github here: https://github.com/VeliovGroup/Meteor-Files/wiki/Google-Cloud-Storage-Integration. I got all my stuff (json file, keys, ids) from Google and then went and put the code in the guide in my images.js file, located in imports/api/images/images.js
import { Meteor } from 'meteor/meteor';
import { Random } from 'meteor/random'
import { FilesCollection } from 'meteor/ostrio:files';
let gcloud, gcs, bucket, bucketMetadata, Request, bound, Collections = {};
if (Meteor.isServer) {
// use require() as "'import' and 'export' may only appear at the top level"
const Random = require('meteor/random');
const Storage = require('@google-cloud/storage');
gcs = new Storage('google-cloud')({
projectId: 'my-project-123', // <-- Replace this with your project ID
keyFilename: 'imports\api\bucketkey.json' // <-- Replace this with the path to your key.json
});
bucket = gcs.bucket('my_bucket'); // <-- Replace this with your bucket name
bucket.getMetadata(function(error, metadata, apiResponse) {
if (error) {
console.error(error);
}
});
Request = Npm.require('request');
bound = Meteor.bindEnvironment(function(callback) {
return callback();
});
}
Collections.files = new FilesCollection({
debug: false, // Set to true to enable debugging messages
storagePath: 'assets/app/uploads/uploadedFiles',
collectionName: 'Images',
allowClientCode: false,
onAfterUpload(fileRef) {
// In the onAfterUpload callback, we will move the file to Google Cloud Storage
_.each(fileRef.versions, (vRef, version) => {
// We use Random.id() instead of real file's _id
// to secure files from reverse engineering
// As after viewing this code it will be easy
// to get access to unlisted and protected files
const filePath = 'files/' + (Random.id()) + '-' + version + '.' + fileRef.extension;
// Here we set the neccesary options to upload the file, for more options, see
// https://googlecloudplatform.github.io/gcloud-node/#/docs/v0.36.0/storage/bucket?method=upload
const options = {
destination: filePath,
resumable: true
};
bucket.upload(fileRef.path, options, (error, file) => {
bound(() => {
let upd;
if (error) {
console.error(error);
} else {
upd = {
$set: {}
};
upd['$set'][`versions.${version}.meta.pipePath`] = filePath;
this.collection.update({
_id: fileRef._id
}, upd, (updError) => {
if (updError) {
console.error(updError);
} else {
// Unlink original files from FS
// after successful upload to Google Cloud Storage
this.unlink(this.collection.findOne(fileRef._id), version);
}
});
}
});
});
});
},
interceptDownload(http, fileRef, version) {
let ref, ref1, ref2;
const path = (ref= fileRef.versions) != null ? (ref1 = ref[version]) != null ? (ref2 = ref1.meta) != null ? ref2.pipePath : void 0 : void 0 : void 0;
const vRef = ref1;
if (path) {
// If file is moved to Google Cloud Storage
// We will pipe request to Google Cloud Storage
// So, original link will stay always secure
const remoteReadStream = getReadableStream(http, path, vRef);
this.serve(http, fileRef, vRef, version, remoteReadStream);
return true;
}
// While the file has not been uploaded to Google Cloud Storage, we will serve it from the filesystem
return false;
}
});
if (Meteor.isServer) {
// Intercept file's collection remove method to remove file from Google Cloud Storage
const _origRemove = Collections.files.remove;
Collections.files.remove = function(search) {
const cursor = this.collection.find(search);
cursor.forEach((fileRef) => {
_.each(fileRef.versions, (vRef) => {
let ref;
if (vRef != null ? (ref = vRef.meta) != null ? ref.pipePath : void 0 : void 0) {
bucket.file(vRef.meta.pipePath).delete((error) => {
bound(() => {
if (error) {
console.error(error);
}
});
});
}
});
});
// Call the original removal method
_origRemove.call(this, search);
};
}
function getReadableStream(http, path, vRef){
let array, end, partial, remoteReadStream, reqRange, responseType, start, take;
if (http.request.headers.range) {
partial = true;
array = http.request.headers.range.split(/bytes=([0-9]*)-([0-9]*)/);
start = parseInt(array[1]);
end = parseInt(array[2]);
if (isNaN(end)) {
end = vRef.size - 1;
}
take = end - start;
} else {
start = 0;
end = vRef.size - 1;
take = vRef.size;
}
if (partial || (http.params.query.play && http.params.query.play === 'true')) {
reqRange = {
start: start,
end: end
};
if (isNaN(start) && !isNaN(end)) {
reqRange.start = end - take;
reqRange.end = end;
}
if (!isNaN(start) && isNaN(end)) {
reqRange.start = start;
reqRange.end = start + take;
}
if ((start + take) >= vRef.size) {
reqRange.end = vRef.size - 1;
}
if ((reqRange.start >= (vRef.size - 1) || reqRange.end > (vRef.size - 1))) {
responseType = '416';
} else {
responseType = '206';
}
} else {
responseType = '200';
}
if (responseType === '206') {
remoteReadStream = bucket.file(path).createReadStream({
start: reqRange.start,
end: reqRange.end
});
} else if (responseType === '200') {
remoteReadStream = bucket.file(path).createReadStream();
}
return remoteReadStream;
}
However, this error occurs:
W20190907-09:22:19.711(2)? (STDERR) C:\Users\NERV\AppData\Local\.meteor\packages\meteor-tool\1.8.1\mt-os.windows.x86_64\dev_bundle\server-lib\node_modules\fibers\future.js:280
W20190907-09:22:19.712(2)? (STDERR) throw(ex);
W20190907-09:22:19.713(2)? (STDERR) ^
W20190907-09:22:19.713(2)? (STDERR)
W20190907-09:22:19.713(2)? (STDERR) TypeError: Storage is not a constructor
W20190907-09:22:19.713(2)? (STDERR) at images.js (imports/api/images/images.js:63:9)
W20190907-09:22:19.713(2)? (STDERR) at fileEvaluate (packages\modules-runtime.js:336:7)
W20190907-09:22:19.714(2)? (STDERR) at Module.require (packages\modules-runtime.js:238:14)
W20190907-09:22:19.714(2)? (STDERR) at Module.moduleLink [as link] (C:\Users\NERV\AppData\Local\.meteor\packages\modules\0.13.0\npm\node_modules\reify\lib\runtime\index.js:38:38)
W20190907-09:22:19.714(2)? (STDERR) at methods.js (imports/api/characters/methods.js:1:463)
W20190907-09:22:19.714(2)? (STDERR) at fileEvaluate (packages\modules-runtime.js:336:7)
W20190907-09:22:19.715(2)? (STDERR) at Module.require (packages\modules-runtime.js:238:14)
W20190907-09:22:19.715(2)? (STDERR) at Module.moduleLink [as link] (C:\Users\NERV\AppData\Local\.meteor\packages\modules\0.13.0\npm\node_modules\reify\lib\runtime\index.js:38:38)
W20190907-09:22:19.715(2)? (STDERR) at main.js (server/main.js:1:146)
W20190907-09:22:19.715(2)? (STDERR) at fileEvaluate (packages\modules-runtime.js:336:7)
W20190907-09:22:19.716(2)? (STDERR) at Module.require (packages\modules-runtime.js:238:14)
W20190907-09:22:19.716(2)? (STDERR) at require (packages\modules-runtime.js:258:21)
W20190907-09:22:19.716(2)? (STDERR) at C:\Users\NERV\Desktop\Projekte\DDCFull\.meteor\local\build\programs\server\app\app.js:4686:1
W20190907-09:22:19.716(2)? (STDERR) at C:\Users\NERV\Desktop\Projekte\DDCFull\.meteor\local\build\programs\server\boot.js:419:36
W20190907-09:22:19.717(2)? (STDERR) at Array.forEach (<anonymous>)
W20190907-09:22:19.717(2)? (STDERR) at C:\Users\NERV\Desktop\Projekte\DDCFull\.meteor\local\build\programs\server\boot.js:228:19
Unable to resolve some modules:
"worker_threads" in /C/Users/NERV/Desktop/Projekte/DDCFull/node_modules/write-file-atomic/index.js (web.browser.legacy)
If you notice problems related to these missing modules, consider running:
meteor npm install --save worker_threads
=> Exited with code: 1
=> Your application is crashing. Waiting for file change.
I don’t know what the problem is, can someone help? I started an issue at github, for additional information: https://github.com/VeliovGroup/Meteor-Files/issues/709