Uploading files to meteor server using Method call - file

I am trying to implement file uploads for meteor using Method call.
I am using this meteor package: https://atmospherejs.com/ostrio/files.
I have no problem on client side (I can send file in a base64 encoded format). on server side I am trying to implement this function : https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/write.md
but I am getting this error.
Error during upload: TypeError: Images.write is not a function
Here is the code of my Method on server:
export const insertImage = new ValidatedMethod({
name: 'images.insert',
validate: new SimpleSchema({
file: { type: String },
}).validator(),
run({ file }) {
Images.write(file, {
fileName: 'sample.png',
type: 'image/png',
}, function (error, fileRef) {
if (error) {
throw error;
} else {
console.log(`${fileRef.name} is successfully saved to FS. _id: ${fileRef._id}`);
}
});
},
});

According to the lib documentation you will need to first instantiate Images with an instance of FilesCollection, similar to as following:
https://github.com/VeliovGroup/Meteor-Files#api-overview-full-api
import { FilesCollection } from 'meteor/ostrio:files';
const Images = new FilesCollection({
collectionName: 'Images',
allowClientCode: false, // Disallow remove files from Client
onBeforeUpload(file) {
// Allow upload files under 10MB, and only in png/jpg/jpeg formats
if (file.size <= 10485760 && /png|jpg|jpeg/i.test(file.extension)) {
return true;
} else {
return 'Please upload image, with size equal or less than 10MB';
}
}
});
For more details on the constructor parameters please refer to https://github.com/VeliovGroup/Meteor-Files/wiki/Constructor

I have used this syntax:
Meteor.call('images.insert', {
file: image
}, (err, res) => {
if (err) {
console.log(`Error during upload: ${err}`);
} else {
console.log(`Upload successfully!`);
}
});

Related

React Native S3 image upload returns "Stream Closed" using XHR

After updating React Native version to latest 0.63.2 and trying to upload the image to S3 bucket XHR returns error Stream Closed image upload was working fine with version 0.61.5
The Code
uploadProfile({ variables: { filetype: mime } }).then(
({ data: { uploadUserProfile } }) => {
const { presignedUrl, url } = uploadUserProfile;
console.log('presignedUrl', { presignedUrl, url });
// uploading to s3 bucket
const xhr = new XMLHttpRequest();
xhr.open('PUT', presignedUrl);
xhr.onreadystatechange = async function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
updateAccount({
variables: {
data: {
profile: url,
},
},
});
} else {
if (/Request has expired/g.test(xhr.response))
Toast({ message: 'slow network connection' });
else {
console.log({
response: xhr.response,
responseText: xhr.responseText,
status: xhr.status,
});
Toast({ message: 'internal server error' });
await report({
error: {
response: xhr.response,
responseText: xhr.responseText,
status: xhr.status,
},
}); // reporting error
}
}
}
};
xhr.setRequestHeader('Content-Type', mime);
xhr.send({ uri: path, type: mime });
setLoading(false);
},
);
When the user wants to upload a profile image first App send a request to the server and get return the pre-signed URL and upload from client-side this how App was working.
I upgraded Flipper to version 0.51.2 and it worked for me.
Go to android/gradle.properties and add this line
FLIPPER_VERSION=0.52.1
You should have the following lines in your android/app/build.gradle
dependencies {
// ....
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
}
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
// ...
}
upgrading flipper version solves the issue for me, If upgrading flipper version doesn't solve for you then try this solution.
Whoever is still struggling with this issue. it's happening because of Flipper network plugin.
I disabled it and things work just fine.
My workaround to make this work is commenting outline number 43
38 NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
39 NetworkingModule.setCustomClientBuilder(
40 new NetworkingModule.CustomClientBuilder() {
41 #Override
42 public void apply(OkHttpClient.Builder builder) {
43 // builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
44 }
45 });
46 client.addPlugin(networkFlipperPlugin);
in this file android/app/src/debug/java/com/maxyride/app/drivers/ReactNativeFlipper.java
found this answer link

Why does RecordRTC always set my mime type to x-matroska

Im trying to record a video from my webcam with the node package 'recordrtc' (im using angular).
Even though i set the mime type in the options to 'video/webm' it always seems to switch it back to 'x-matroska'...
Here is my code:
[...]
this.options = {
mimeType: 'video/webm',
bitsPerSecond: 51200000,
frameRate: 60
}
// After getting the Video Devices
this.recordRTC = RecordRTC(stream, this.options);
[...]
startRecording() {
this.recordRTC.startRecording();
}
stopRecording() {
this.recordRTC.stopRecording(this.processVideo.bind(this));
}
processVideo(videoWebMural) {
console.log(this.recordRTC.getBlob());
this.recordRTC.getDataURL((url) => {
console.log(url);
})
}
For some reason when i console log this blob, it says
> Blob {size: 149322, type: 'video/x-matroska;codecs=avc1'}
And when i log the base64 string of the video with 'this.recordRTC.getDataURL' it aswell starts with:
> data:video/x-matroska [...]
What am i doing wrong here?
Maybe you can try this
this.options = {
type: 'video',
mimeType: 'video/webm\;codecs=vp9',
recorderType: MediaStreamRecorder,
bitsPerSecond: 51200000,
frameRate: 60
}

Loopback4 File upload Storage component Example

I’m looking for an example for a file store using loopback4, could someone provide the controller configuration for file crud operations?
LoopBack 4 does not provide a built-in parser for multipart file upload requests. Instead, we provide extension points allowing applications to use a 3rd party parsers like multer.
There are two options how to write a controller accepting file uploads. You can learn more about this topic in our docs, see Parsing requests and Extending request body parsing
1. Handle file uploads in the controller method
Instruct LoopBack to pass the raw body stream to your controller method. In the controller method, call the file-upload parser to process the multi-part stream.
Benefits: different endpoints may want to process the uploaded files differently. By implementing file-upload parsing in a controller method, it's easy to customize all aspects of this process.
Cross-posting an example from file-upload.acceptance.ts:
import * as multer from 'multer';
class FileUploadController {
#post('/show-body', {
responses: {
// (left out for brevity)
},
})
async showBody(
#requestBody({
description: 'multipart/form-data value.',
required: true,
content: {
'multipart/form-data': {
// Skip body parsing
'x-parser': 'stream',
schema: {type: 'object'},
},
},
})
request: Request,
#inject(RestBindings.Http.RESPONSE) response: Response,
): Promise<Object> {
const storage = multer.memoryStorage();
const upload = multer({storage});
return new Promise<object>((resolve, reject) => {
upload.any()(request, response, err => {
if (err) reject(err);
else {
resolve({
files: request.files,
fields: (request as any).fields,
});
}
});
});
}
2. Implement & register a body parser for multi-part file uploads
In this option, all file-uploads are processed at transport layer in the same way for all controller methods. Controller methods receive parsed data.
Example body parser implementation from file-upload-with-parser.acceptance.ts:
class MultipartFormDataBodyParser implements BodyParser {
name = 'multipart/form-data';
supports(mediaType: string) {
// The mediaType can be
// `multipart/form-data; boundary=--------------------------979177593423179356726653`
return mediaType.startsWith('multipart/form-data');
}
async parse(request: Request): Promise<RequestBody> {
const storage = multer.memoryStorage();
const upload = multer({storage});
return new Promise<RequestBody>((resolve, reject) => {
upload.any()(request, {} as any, err => {
if (err) reject(err);
else {
resolve({
value: {
files: request.files,
fields: (request as any).fields,
},
});
}
});
});
}
}
An example controller leveraging this body parser:
class FileUploadController {
#post('/show-body', {
responses: {
// (left out for brevity)
},
})
async showBody(
#requestBody({
description: 'multipart/form-data value.',
required: true,
content: {
'multipart/form-data': {
schema: {type: 'object'},
},
},
})
{files, fields}: any,
) {
return body;
}
}

Option to “Select Image From Gallery or Camera”

I want to make an option to "Select Image From Gallery or Camera". I have tried many modules but they are only providing access to the gallery directly. I am using expo tool for creating a react native application. First I want a popup to open then then the user has to pick an option then the user is redirected according to that option. If you have any suggestion, please help me.
I´ve seen it done with React Native Image Picker, look for it in github:
https://github.com/react-community/react-native-image-picker
Add dependencies:
dependencies {
compile project(':react-native-image-picker')
}
Add permissions:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Usage:
var ImagePicker = require('react-native-image-picker');
// More info on all the options is below in the README...just some common use cases shown here
var options = {
title: 'Select Avatar',
customButtons: [
{name: 'fb', title: 'Choose Photo from Facebook'},
],
storageOptions: {
skipBackup: true,
path: 'images'
}
};
/**
* The first arg is the options object for customization (it can also be null or omitted for default options),
* The second arg is the callback which sends object: response (more info below in README)
*/
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
}
else {
let source = { uri: response.uri };
// You can also display the image using data:
// let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
avatarSource: source
});
}
});
If you would like to directly start just the camera or the gallery, use it like this:
// Launch Camera:
ImagePicker.launchCamera(options, (response) => {
// Same code as in above section!
});
// Open Image Library:
ImagePicker.launchImageLibrary(options, (response) => {
// Same code as in above section!
});
Hope it helps.

Can I open folder using $cordovaFileOpener in ionic mobile app?

I can see the example to open file (PDF, mp3 etc) but how to open folder which is created by my app only. I'm not sure what to pass in second argument for file type as I want to open folder.
Below is not working
$cordovaFileOpener2.open(
cordova.file.externalRootDirectory + "MyFolder/",
''
).then(function() {
// Success!
}, function(err) {
// An error occurred. Show a message to the user
});
To get all files of a folder, I use native API. I made a function that receives the path and returns an array of FileEntry.
In ES2015(ES6):
function getFiles(path) {
return new Promise((resolve, reject) =>
resolveLocalFileSystemURL(path, fileSystem => {
let directoryReader = fileSystem.createReader();
directoryReader.readEntries(entries => resolve(entries), error => reject(error));
}, error => reject(error)));
}
An example of FileEntry returned by function is:
FileEntry {
isFile: true,
isDirectory: false,
name: "file.pdf",
fullPath: "/Android/data/app/file.pdf",
filesystem: FileSystem
}
In addition, you can open each file with fileOpener2:
$cordovaFileOpener2.open(file.nativeURL, 'application/pdf');
To open all types of files/folder use the following plugin,
cordova plugin add https://github.com/pwlin/cordova-plugin-file-opener2.git
Then use the following code,
$cordovaFileOpener2.open(
'path',
'application/*'
).then(function() {
// Success!
}, function(err) {
// An error occurred. Show a message to the user
});
Reference: http://ngcordova.com/docs/plugins/fileOpener2/

Resources