Search code examples
javascriptparse-platformparse-server

'RequestError: Error: Invalid URI' when uploading file to parse server cloud


I am using this sample code from the parse javascript sdk in main.js of my electron app, it works fine with the example URI, but when i use my own URI, which is to a local file at the route level of my app, I get the following RequestError message,

Error: Invalid URI.

The URI i am trying to use is file://${__dirname}/tempInv.pdf I have tried every different variation of the file's address I can think of, but still the same result. Is there some way of point to localhost maybe that would get past this error. The app will be deployed so needs to work across platforms.

const request = require('request-promise');
const Parse = require('parse/node');

....

const options = {
  uri: 'https://-----/-----',
  resolveWithFullResponse: true,
  encoding: null, // <-- this is important for binary data like images.
};

request(options)
  .then((response) => {
    const data = Array.from(Buffer.from(response.body, 'binary'));
    const contentType = response.headers['content-type'];
    const file = new Parse.File('logo', data, contentType);
    return file.save();
  })
  .then((file => console.log(file.url())))
  .catch(console.error);
const Parse = require('parse/node');

const express = require('express');
const XeroClient = require('xero-node').AccountingAPIClient;
const config = require('./config.json');

const fs  = require('fs');

const request = require('request-promise');

let appEx = express();

let lastRequestToken = null;
let xeroClient = new XeroClient(config);


appEx.set('port', 3000)

ipcMain.on('message-createInvoice', function (event, data) {

    let win = new BrowserWindow({ width: 340, height: 480 });
        win.setPosition(0, 0);
        win.loadURL('http://localhost:3000/');

    appEx.get('/', async function(req, res) {

        lastRequestToken = await xeroClient.oauth1Client.getRequestToken();
        let authoriseUrl = xeroClient.oauth1Client.buildAuthoriseUrl(lastRequestToken);

        res.redirect(authoriseUrl);

    })   


    appEx.get('/callback', async function(req, res) {

        let oauth_verifier = req.query.oauth_verifier;
        let accessToken = await xeroClient.oauth1Client.swapRequestTokenforAccessToken(lastRequestToken, oauth_verifier)
            .then(async() => {
                var invoice = await xeroClient.invoices.create(data)           
                    .then((invoice) => {
                        var inv = invoice["Invoices"][0];
                        var invId = inv["InvoiceID"];

                        xeroClient.invoices.savePDF({ InvoiceID: invId, savePath: path.join(__dirname, '../temp-files/temp-inv.pdf',)})
                            .then(() => {

                                Parse.initialize("--appId--");    
                                Parse.serverURL = 'http://--.---.--.---:80/parse';

                                const data = fs.readFileSync(path.join(__dirname, '../temp-files/temp-inv.pdf'));

                                const file = await new Parse.File('inv.pdf', [...data]);
                                return file.save()
                                    .then((file) => {
                                        var Invoices = Parse.Object.extend("Invoices");
                                        var invoice = new Invoices;
                                        invoice.set('invPdf', file);
                                        invoice.save();     
                                        event.returnValue = true;
                                        win.close();
                                    })
                                    .catch((err) => {
                                    console.log('Failed to save invoice to Parse Cloud: ' + err);
                                    event.returnValue = false;
                                    win.close();
                                    })

                            })
                            .catch((err) => {
                            console.log('Failed to save invoice to temp-file: ' + err);
                            event.returnValue = false;
                            win.close();
                            })
                    })
                    .catch((err) => {
                    console.log('Failed to create invoice in xero' + err);
                    event.returnValue = false;
                    win.close();
                    })
            })
            .catch((err) => {
                console.log('Oauth failed' + err);
                event.returnValue = false;
                win.close();
            })
    })

    event.sender.send('message-createInvoice', true);

});


appEx.listen(appEx.get('port'), function() {
    console.log("Your Xero basic public app is running at http://localhost:" + appEx.get('port'))
})


Solution

  • I think that request-promise is not the best way to read a local file. I recommend you to use fs package. It would be something like this:

    const path = require('path');
    const fs = require('fs');
    const Parse = require('parse/node');
    
    ....
    
    const data = fs.readFileSync(path.join(__dirname, './tempInv.pdf'));
    const file = new Parse.File('logo.pdf', [...data]);
    file.save()
      .then(file => console.log(file.url()))
      .catch(console.error);