I'm using react-native-mail in my React Native app. This is my code:
const path = RNFetchBlob.fs.dirs.CacheDir + '/' + SHA1(this.fileSource.uri) + '.pdf'
const self = this;
let data = this.fileSource.uri.replace(/data:application\/pdf;base64\,/i, '');
RNFetchBlob.fs
.writeFile(path, data, 'base64')
.then(() => {
Mailer.mail({
subject: "Subject",
body: "",
recipients: [this.props.emailAddress],
attachment: {
path: path,
type: 'pdf',
name: `attachment.pdf`,
}
}, (error) => {
...
});
})
.catch(() => {
...
})
The value of path is "/data/user/0/com.<my-app-name>/cache/5cae2ea1e235873729dd158e19f3d122a1b46c73.pdf"
The value of data is TIAoxIDAgb2JqIAo8PCAKL1R5cGUgL0NhdGFsb2cgCi9QYWdlcyAyIDAgUiAKL1BhZ2VNb... (very long)
The mail() method throws the error Failed to find configured root that contains /data/user/0/com.<my-app-name>/cache/5cae2ea1e235873729dd158e19f3d122a1b46c73.pdf
Android version: 11
react-native: 0.63.4
rn-fetch-blob: 0.12.0
react-native-mail: git+https://github.com/marcinolek/react-native-mail.git
Does anyone know how I can approach this?
Try changing the file location on an external path.
Related
taking a course where we integrate Clarifai Face Detection API into our app and the course shows a section on Clarifai's documents where you can copy some JavaScript code under what looks like "Request" and it has
app.models.predict(Model ID, Web Address)
function(response) {
},
function(err) {
}
);
Which is then used under our onSubmitRequest input. Any tips on where to find this?
Thanks much
we generally don't recommend using this JS package as it is no longer supported [R]. Please use the NodeJS gRPC variant: https://www.npmjs.com/package/clarifai-nodejs-grpc or call our REST API directly: https://docs.clarifai.com/api-guide/predict/images (see "Javascript (REST)" code snippets)
I think that we just took the same online course and in order to accomplish that step, you will need to update your code basis according to the new Clarifai standards. I did that and it worked as follows:
Note:
You will need to modify the USER_ID, PAT and APP_ID with your own credentials.
Also, you will be using the result variable insted of the response variable.
In case you run into error or have any dubts check these links:
https://help.clarifai.com/hc/en-us/articles/4408131912727-How-do-I-find-my-user-id-app-id-and-PAT-
https://help.clarifai.com/hc/en-us/articles/1500007677141-Where-to-find-your-Model-IDs-and-Model-Version-IDs
onButtomSubmit = () => {
//help me => user_id can be found in multiple ways, one way is in https://portal.clarifai.com/settings/profile
const USER_ID = "Use-your-ID-here";
// Your PAT (Personal Access Token) can be found in the portal under Authentification
// help me => PAT can be found in https://portal.clarifai.com/settings/authentication (create one if necessary!)
const PAT = "Use-your-APi-Here";
// help me => App Id is just the name of your app on the portal.
const APP_ID = "Use-your-app-name-here";
// Change these to whatever model and image input you want to use
// help me => https://help.clarifai.com/hc/en-us/articles/1500007677141-Where-to-find-your-Model-IDs-and-Model-Version-IDs
const MODEL_ID = "face-detection";
const MODEL_VERSION_ID = "45fb9a671625463fa646c3523a3087d5";
const IMAGE_URL = this.state.input;
///////////////////////////////////////////////////////////////////////////////////
// YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
///////////////////////////////////////////////////////////////////////////////////
const raw = JSON.stringify({
user_app_id: {
user_id: USER_ID,
app_id: APP_ID,
},
inputs: [
{
data: {
image: {
url: IMAGE_URL,
},
},
},
],
});
const requestOptions = {
method: "POST",
headers: {
Accept: "application/json",
Authorization: "Key " + PAT,
},
body: raw,
};
fetch(
"https://api.clarifai.com/v2/models/" +
MODEL_ID +
"/versions/" +
MODEL_VERSION_ID +
"/outputs",
requestOptions
)
.then((response) => response.json())
.then((result) =>
console.log(result)
)
.catch((error) => console.log("error", error));
};
have fun :)
Issue Summary
If I try to send an email with attachment added, I get no Promise resolve and no response, However, if I comment out the attachment logic, I receive an error (I entered invalid token to get an error), like I expected. The path to the doc file is real, but for this piece of code I changed it.
Code not working:
const fs = require('fs');
const sgMail = require('#sendgrid/mail');
(async () => {
sgMail.setApiKey('SG.XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXXX');
const pathToAttachment = 'Path\\To\\doc\\file.doc';
const attachment = fs.readFileSync(pathToAttachment).toString('base64');
const msg = {
to: 'myemail#gmail.com',
from: 'youremail#gmail.com',
subject: 'test',
text: 'test',
attachments: [
{
content: attachment,
filename: 'file.doc',
type: 'application/doc',
disposition: 'attachment'
}
]
};
let result = null;
try {
result = await sgMail.send(msg);
console.log('sent!');
} catch (err) {
console.error(err.toString());
}
console.log(`result: ${result}`);
})();
Not getting any response, the code ignores the rest of any code that goes after the 'send' function.
Code working:
const fs = require('fs');
const sgMail = require('#sendgrid/mail');
(async () => {
sgMail.setApiKey('SG.XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXXX');
const pathToAttachment = 'Path\\To\\doc\\file.doc';
const attachment = fs.readFileSync(pathToAttachment).toString('base64');
const msg = {
to: 'myemail#gmail.com',
from: 'youremail#gmail.com',
subject: 'test',
text: 'test',
/* attachments: [
{
content: attachment,
filename: 'file.doc',
type: 'application/doc',
disposition: 'attachment'
}
] */
};
let result = null;
try {
result = await sgMail.send(msg);
console.log('sent!');
} catch (err) {
console.error(err.toString());
}
console.log(`result: ${result}`);
})();
Code works as I expected, getting:
Unauthorized (401)
The provided authorization grant is invalid, expired, or revoked
null
null
result: null
Technical details:
"#sendgrid/mail": "^7.4.0"
node version: v14.15.1
I posted an issue on this on the their GitHub page:
https://github.com/sendgrid/sendgrid-nodejs/issues/1220
But they seem not to be able to produce the bug.Has anyone else faced this issue before?
As I write to SendGrid developers, they admit it's a bug on their package and it will be fixed:
"#orassayag Thanks for providing more information. I was able to
recreate this issue and it looks like a bug on our end. We will add it
to our internal backlog to be prioritized. Pull requests and +1s on
the issue summary will help it move up the backlog. In the meantime I
would suggest using node version 12.20.0 and Sendgrid/mail: 7.4.0 as a
work around solution for now. Using these versions, I was able to get
the error logs to show up when attaching the same file."
Question close.
here
I am trying to upload a file from mobile to google bucket using ionic 4. Although a file can upload into the could. I am struggling to get the file properties out of file object.
Here is my method,
async selectAFile() {
const uploadFileDetails = {
name: '',
contentLength: '',
size: '',
type: '',
path: '',
};
this.fileChooser.open().then(uri => {
this.file.resolveLocalFilesystemUrl(uri).then(newUrl => {
let dirPath = newUrl.nativeURL;
const dirPathSegments = dirPath.split('/');
dirPathSegments.pop();
dirPath = dirPathSegments.join('/');
(<any>window).resolveLocalFileSystemURL(
newUrl.nativeURL,
function(fileEntry) {
uploadFileDetails.path = newUrl.nativeURL;
const file: any = getFileFromFileEntry(fileEntry);
//log 01
console.log({ file });
uploadFileDetails.size = file.size;
uploadFileDetails.name = `${newUrl.name
.split(':')
.pop()}.${file.type.split('/').pop()}`;
uploadFileDetails.type = file.type;
async function getFileFromFileEntry(fileEntry) {
try {
return await new Promise((resolve, reject) =>
fileEntry.file(resolve, reject)
);
} catch (err) {
console.log(err);
}
}
},
function(e) {
console.error(e);
}
);
});
});
// here uploadFileDetails is simller to what I declared at the top ;)
// I wan't this to be populated with file properties
// console.log(uploadFileDetails.name) --> //''
const uploadUrl = await this.getUploadUrl(uploadFileDetails);
const response: any = this.uploadFile(
uploadFileDetails,
uploadUrl
);
response
.then(function(success) {
console.log({ success });
this.presentToast('File uploaded successfully.');
this.loadFiles();
})
.catch(function(error) {
console.log({ error });
});
}
even though I can console.log the file in log 01. I am unable to get file properties like, size, name, type out of the resolveLocalFileSystemURL function. basically, I am unable to populate uploadFileDetails object. What am I doing wrong? Thank you in advance.
you actually need 4 Ionic Cordova plugins to upload a file after getting all the metadata of a file.
FileChooser
Opens the file picker on Android for the user to select a file, returns a file URI.
FilePath
This plugin allows you to resolve the native filesystem path for Android content URIs and is based on code in the aFileChooser library.
File
This plugin implements a File API allowing read/write access to files residing on the device.
File Trnafer
This plugin allows you to upload and download files.
getting the file's metadata.
file.resolveLocalFilesystemUrl with fileEntry.file give you all the metadata you need, except the file name. There is a property called name in the metadata but it always contains value content.
To get the human readable file name you need filePath. But remember you can't use returning file path to retrieve metadata. For that, you need the original url from fileChooser.
filePathUrl.substring(filePathUrl.lastIndexOf('/') + 1) is used to get only file name from filePath.
You need nativeURL of the file in order to upload it. Using file path returning from filePath is not going to work.
getFileInfo(): Promise<any> {
return this.fileChooser.open().then(fileURI => {
return this.filePath.resolveNativePath(fileURI).then(filePathUrl => {
return this.file
.resolveLocalFilesystemUrl(fileURI)
.then((fileEntry: any) => {
return new Promise((resolve, reject) => {
fileEntry.file(
meta =>
resolve({
nativeURL: fileEntry.nativeURL,
fileNameFromPath: filePathUrl.substring(filePathUrl.lastIndexOf('/') + 1),
...meta,
}),
error => reject(error)
);
});
});
});
});
}
select a file from the file system of the mobile.
async selectAFile() {
this.getFileInfo()
.then(async fileMeta => {
//get the upload
const uploadUrl = await this.getUploadUrl(fileMeta);
const response: Promise < any > = this.uploadFile(
fileMeta,
uploadUrl
);
response
.then(function(success) {
//upload success message
})
.catch(function(error) {
//upload error message
});
})
.catch(error => {
//something wrong with getting file infomation
});
}
uploading selected file.
This depends on your backend implementation. This is how to use File Transfer to upload a file.
uploadFile(fileMeta, uploadUrl) {
const options: FileUploadOptions = {
fileKey: 'file',
fileName: fileMeta.fileNameFromPath,
headers: {
'Content-Length': fileMeta.size,
'Content-Type': fileMeta.type,
},
httpMethod: 'PUT',
mimeType: fileMeta.type,
};
const fileTransfer: FileTransferObject = this.transfer.create();
return fileTransfer.upload(file.path, uploadUrl, options);
}
hope it helps. :)
I am following the how to graphql tutorial where I am setting up a simple graphql server.
index.js
const { GraphQLServer } = require('graphql-yoga');
// 1
let links = [{
id: 'link-0',
url: 'www.howtographql.com',
description: 'Fullstack tutorial for GraphQL'
}];
const resolvers = {
Query: {
info: () => `This is the API of a Hackernews Clone`,
// 2
feed: () => links,
},
// 3
Link: {
id: (parent) => parent.id,
description: (parent) => parent.description,
url: (parent) => parent.url,
}
};
// 3
const server = new GraphQLServer({
typeDefs:'./schema.graphql',
resolvers,
});
server.start(() => console.log(`Server is running on http://localhost:4000`));
As you can see, I am referencing my schema file when creating the GraphQLServer. When I run the server, however, I am getting the following error:
/Users/BorisGrunwald/Desktop/programmering/Javascript/GraphQL/hackernews-node/node_modules/graphql-yoga/dist/index.js:418
throw new Error("No schema found for path: " + schemaPath);
^
My file structure:
Can anyone spot the error?
You gave the path ./schema.graphql which makes node look for the file in the directory where you run it instead of the correct location which is 'src/schema.graphql'.
So you need to change the path to:
//...
typeDefs: 'src/schema.graphql',
//...
I am trying to implement IPFS in an application made with NodeJS. I can add file and get the CID, but if I try to download it with ipfs get <CID> it does not download anything. Any ideas what can be ?. I use this code to start an IPFS node:
const IPFS = require('ipfs');
// Spawn your IPFS node \o/
const node = new IPFS();
node.on('ready', () => {
node.id((err, id) => {
if (err) {
return console.log(err)
}
console.log(id)
})
let files = [
{
path: '/home/my/file.jpg',
content: File.read('/home/my/file.jpg', null)
}
]
node.files.add(files, function (err, files) {
if (err) {
console.log(err);
} else {
console.log(files)
}
})
})
When you start the node application, you will get some output like this:
[ { path: 'home/my/Pictures',
hash: '...hash',
size: 10329 },
{ path: 'home/my',
hash: '...hash',
size: 10384 },
{ path: 'home',
hash: '...hash',
size: 10435 },
{ path: '/home/my/Pictures/google.png',
hash: 'QmYeznhKxbZY37g5ymFzWnmrbP8ph2fdxycAuw9S9goUYr',
size: 10272 } ]
then copy that file hash, make sure you can access that file from the browser.
// replace the hash code for your own need
https://ipfs.io/ipfs/QmYeznhKxbZY37g5ymFzWnmrbP8ph2fdxycAuw9S9goUYr
then download the file in your terminal
// replace the hash code for your own need
ipfs get QmYeznhKxbZY37g5ymFzWnmrbP8ph2fdxycAuw9S9goUYr -o=google.png
Check here for more options
From nodejs you can do something like this provided necessary packages are imported:
const fileHash = 'you hash of the file you want to get'
ipfs.files.get(fileHash, function (err, files) {
files.forEach((file) => {
console.log(file.path)
console.log("File content >> ",file.content.toString('utf8'))
})
})