node.js – How to give permission to files in android using cordova-ThrowExceptions

Exception or error:

I have created a vue project where I am using cordova as plugin in vue. I have a scenario where using cordova file-transfer plugin I want to upload the file on to the server I have created in node.js using multer package.

I can able to select the files but the files aren’t getting upload because of some permission denial.
So how can I resolve my problem I have added the permissions in AndroidManifest.xml file but still its denying my permission I don’t what the hell is wrong with this application.

Any help would be appreciated…

CLIENT SIDE CODE

<template>
    <div><br>
        <hr><br><br>
        <v-btn color="warning" @click="selectFiles()">Upload Files</v-btn>
    </div>
</template>

<script>
export default {
    data() {
        return { 
        }
    },
    mounted() {
        document.addEventListener("deviceready", onDeviceReady , false);
        function onDeviceReady() {
            console.log(window.FileTransfer);
        }
    },
    methods: {
        selectFiles() {
            window.fileChooser.open((file) => {
                this.upload(file.uri + file.name)
            })
        },
        upload(fileURL){
            var permissions = window.cordova.plugins.permissions;
            permissions.hasPermission(permissions.CAMERA, function( status ){
            if ( status.hasPermission ) {
                alert("Yes :D ");
            }
            else {
                alert("No :( ");
                 permissions.requestPermissions(
                    [permissions.ACTION_OPEN_DOCUMENT],
                    function(status) {
                        if( !status.hasPermission ) alert("hhh");
                    },
                   alert('Camera or Accounts permission is not turned on'));
            }
            });

            var path = fileURL
            path = path.replace("%", "%25");
            alert('path: '+path)
            fileURL = path
            var options = new window.FileUploadOptions();
            options.fileKey = "image";
            options.httpMethod = 'POST';
            options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
            options.mimeType = "image/jpeg";
            var ft = new window.FileTransfer();
            ft.upload(fileURL, encodeURI("http://localhost:8000/user/fileUpload"), (r)=>
            { 
                console.log("Code = " + r.responseCode);
                console.log("Response = " + r.response);
                console.log("Sent = " + r.bytesSent);}, (error)=>{
                alert(JSON.stringify(error));
                console.log("upload error source " + error.source);
                console.log("upload error target " + error.target);
                }, options);
        }
    }
}
</script> 

SERVER SIDE CODE

var express = require('express');
const app = express();
const port = 8000;
app.get('/', (req, res) => {
    res.send('hello people');
});

var multer = require('multer');

var storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, '/upload');
     },
    filename: function (req, file, cb) {
        cb(null , file.originalname);
    }
});



var upload = multer({dest:'uploads/'});
// var upload = multer({ storage: storage })




app.post('/user/fileUpload', upload.single('image'), (req, res) => {
    try {
      res.send(req.file);
    }catch(err) {
      res.send(400);
    }
  });

  app.listen(port, () => {
    console.log('listening to the port: ' + port);
});

AndroidManifest.xml

<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="10000" android:versionName="1.0.0" package="com.vue.example.app" xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.camera" android:required="true" />
    <application android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true">
        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
            <intent-filter android:label="@string/launcher_name">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true" android:name="org.apache.cordova.camera.FileProvider">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/camera_provider_paths" />
        </provider>
    </application>
</manifest>

When I am selecting the image file from the folder its giving me the alert message of Camera or Accounts permission is not turned on and then its giving the alert message of something like this:-

{"code";3,"source"."content://com.android.providers.media.documents/document/image%253A1961Image-name.jpg","target":my server api. "Permission Denial":reading com.android.providers.media.documents/MediaDocumentsProvideruri requires that you obtain access using ACTION_OPEN_DOCUMENT or related API's.

How to solve:

I solved it the only thing I was doing wrong is that I was passing the name of file with its uri, we only need to pass the uri in fileChooser.open() function. I will post the client side code. Here is the solution :-

SOLVED CLIENT CODE

<template>
    <div><br>
        <hr><br><br>
        <v-btn color="warning" @click="selectFiles()">Upload Files</v-btn>
    </div>
</template>

<script>
export default {
    data() {
        return {
        }
    },
    mounted() {
        document.addEventListener("deviceready", onDeviceReady , false);
        function onDeviceReady() {
            console.log(window.FileTransfer);
        }
    },
    methods: {
        selectFiles() {
            window.fileChooser.open((file) => {
                this.upload(file.uri);
            })
        },
        upload(fileURL) {
            var options = new window.FileUploadOptions();
            options.fileKey = "image";
            options.httpMethod = 'POST';
            options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
            options.mimeType = "image/jpeg";
            var ft = new window.FileTransfer();
            ft.upload(fileURL, encodeURI("http://192.168.1.111:8000/user/fileUpload"), (r)=>
            { 
                alert("uploaded successfully..")
                console.log("Code = " + r.responseCode);
                console.log("Response = " + r.response);
                console.log("Sent = " + r.bytesSent);}, (error)=>{
                alert(JSON.stringify(error));
                console.log("upload error source " + error.source);
                console.log("upload error target " + error.target);
            }, options);
        }
    }
}
</script> 

Leave a Reply

Your email address will not be published. Required fields are marked *