Ionic Cordova Camera Image Upload Issue - android

I am using MediaCapture library but getting 403. Below is my code:
MediaCapture.captureImage(options).then(
async (data: any) => {
const contents: any = await Filesystem.readFile({
path: data[0].fullPath,
});
setPreviewImage(contents);
let blobData: any = {};
let formdata = new FormData();
formdata.append(
"file",
`data:${data[0].type};base64,${contents.data}`
);
const response = (await axios.post(
Endpoints.userCover,
formdata
)) as ServerResponse;
if (response.status) {
console.log(response);
console.log("-------------------- IMAGE Camera");
}
},
(err) => console.error(err, " error")
);
enter image description here
Getting 403 on MediaCapture library when using Camera but it's working when selecting image from the android Gallery.

Related

Expo React Native PDF download invalid format

I'm using expo file system to download a pdf. It was successfully downloaded however when trying to open a pdf file it says "Cannot display a pdf of invalid format. First I downloaded pdf from backend and then converted to base64 using buffer.
Here's the reference I followed from stackoverflow Expo React Native, saving PDF files to Downloads folder
import * as FileSystem from 'expo-file-system';
import { StorageAccessFramework } from 'expo-file-system';
import {Buffer} from "buffer";
const downloadFile = async (payment) => {
const pdf = await grabPdf();
const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync();
if (!permissions.granted) {
return;
}
try {
await StorageAccessFramework.createFileAsync(permissions.directoryUri, 'inv'+payment.invoice_number, 'application/pdf')
.then(async(uri) => {
await FileSystem.writeAsStringAsync(uri, pdf, { encoding: FileSystem.EncodingType.Base64 });
Alert.alert('Success', 'Successfully downloaded')
})
.catch((e) => {
console.log(e.response.data);
alert(e)
});
} catch (e) {
throw new Error(e);
alert(e)
}
}
Download pdf from backend and convert to base 64 using buffer.
const grabPdf = async () => {
axiosConfig.defaults.headers.common['Authorization'] = `Bearer ${user.token}`;
const response = await axiosConfig('/user/invoice/C0F19758-0001/247')
.catch(error => {
console.log('Error: ', error.response.data)
alert('Error: '+ error.response.data)
});
const buff = Buffer.from(response.data, 'base64')
return buff.toString('base64')
}
Solved this problem by converting pdf to base64 from php backend
$base64 = chunk_split(base64_encode(file_get_contents($filename)));
return $base64;
before passing to react-native

Uploading blob with XMLHttpRequest doesn't work in Android - React Native/Expo

I'm using Firestore v9 within Expo/React Native. I use XMLHttpRequest to convert a base64 image into a blob file. Then I send/upload that blob file to Firebase Storage. It works perfectly with iOS but not with Android. In Android it returns {istrusted: false}, like the network request is not sent or something went wrong during converting the base64 image into a blob file.
I tried to use react-native-fetch-blob library as mentioned here but it's not supported by Expo.
This is my code:
const getBlob = async (photo) => {
return await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
console.log("consoleloge",e);
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", photo, true);
xhr.send(null);
});
}
const upload64BaseImage = async (photo, newDocRef) => {
try {
const blob = await getBlob(photo)
const imageRef = ref(storage, `images/${newDocRef}.jpg`);
const metadata = {
contentType: "image/jpeg",
};
const snapshot = await uploadBytes(imageRef, blob, metadata);
const downloadUrl = await getDownloadURL(snapshot.ref);
return downloadUrl;
} catch (error) {
console.log(`error`, error.message);
}
};

Uploading image to firebase in react native: undefined is not a function

As the title says, I'm trying to upload Image to firebase in react native. I'm using react-native-image-picker and firebase modules for that. My code goes as: (Only including the "main" parts for clarity)
import ImagePicker from 'react-native-image-picker';
...
//called on pressing a button
onChooseImagePress = async () => {
let result = await ImagePicker.open({ //error occurs here
takePhoto: true,
useLastPhoto: true,
chooseFromLibrary: true
});
if (!result.cancelled) {
this.uploadImage(result.uri, "test-image")
.then(() => {
Alert.alert("Success");
})
.catch((error) => {
Alert.alert(error);
});
}
}
uploadImage = async (uri, imageName) => {
const response = await fetch(uri);
const blob = await response.blob();
var ref = firebase.storage().ref('images').child("userName/" + imageName);
return ref.put(blob);
}
....
Issue:
I am getting this error: undefined is not a function. Here's a screenshot of the same:
I'm not sure what it even means, since ImagePicker has an open function. Please note that I have provided the desired permissions. So it is not an issue due to that. Please help me resolve this. Thanks...
Are you using React-native ImagePicker? There is no open in the API document.
API Reference of react-native-image-picker
This is the default example of getting the value of the selected image you want.
import ImagePicker from 'react-native-image-picker';
// More info on all the options is below in the API Reference... just some common use cases shown here
const 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 in the API Reference)
*/
ImagePicker.launchImageLibrary(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 {
const source = { uri: response.uri };
// You can also display the image using data:
// const source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
avatarSource: source,
});
}
});

Upload image to server with XMLHttpRequest and FormData in React-Native

I am trying to upload image to server with progress by using the example provided by:
https://gist.github.com/Tamal/9231005f0c62e1a3f23f60dc2f46ae35
I checked some tutorials, the code should works. But the uri in Android show uri
uri: content://media/external/images/media/4985
The URI come from the component
https://github.com/jeanpan/react-native-camera-roll-picker
The URI should be
file://....
So, why the upload code not working.
How can I convert the
content://... to file://.... to make it possible to upload image to server in React-native? or does my assumed is correct?
I am using react-native-image-picker to get image from library. I have written following code in one method name as selectPhoto() to select image from library.
selectedPhoto = () => {
//Open Image Picker
const options = {
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
};
ImagePicker.showImagePicker(options, (response) => {
//console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled photo 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};
console.log(source.uri);
this.setState({
profilePhoto: source
});
}
}); }
This will give me uri of selected image and I have set in state variable. then write following code to upload image.
var profiePicture = {
uri: this.state.profilePhoto.uri,
type: 'image/jpg', // or photo.type image/jpg
name: 'testPhotoName',
}
// API to upload image
fetch('http://www.example.com/api/uploadProfilePic/12345', {
method: 'post',
headers:{
'Accept': 'application/json',
'content-type': 'multipart/form-data',
},
body: JSON.stringify({
'profile_pic' : profiePicture
})
}).then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
})
.catch((error) => {
console.error(error);
});
This code is working in one of the my project.

react-native upload pictures on android

I have a react-native app on Android and a backend server written in NodeJS + Express and I'm using multer to handle file uploads.
const multer = require('multer');
const mime = require('mime');
const crypto = require('crypto');
const storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, config.uploads),
filename: (req, file, cb) => {
crypto.pseudoRandomBytes(16, (err, raw) => {
cb(null, raw.toString('hex') + Date.now() + '.' + mime.extension(file.mimetype));
});
}
});
const upload = multer({ storage });
const Router = require('express').Router;
const controller = require('./upload.controller');
const router = new Router();
const auth = require('./../../auth/auth.service');
router.post('/', [auth.isAuthenticated(), upload.any()], controller.create);
module.exports = router;
And on my react-native app I try to do like this:
ImagePicker.launchCamera(options, image => {
let { uri } = image
const API_URL = 'http://192.168.1.2:9000/api/uploads'
var form = new FormData();
form.append("FormData", true)
form.append("access_token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjU3YjgyZGQ2MTEwZDcwYmEwYjUxZjM5YyIsImlzTWVkaWMiOnRydWUsImlhdCI6MTQ3MTY4ODE1MiwiZXhwIjoxNDcxNzA2MTUyfQ.gPeql5g66Am4Txl1WqnbvOWJaD8srTK_6vihOJ6kFbY")
form.append("Content-Type", "image/jpg")
form.append('image', uri)
fetch(API_URL, {body: form, mode: "FormData", method: "post", headers: {"Content-Type": "multipart/form-data"}})
.then((response) => console.log(response))
.catch((error) => {
console.log("ERROR " + error)
})
.then((responseData) => {
console.log("Succes "+ responseData)
})
.done();
})
But when I try to upload I recive the following error
multipart body must have at least one part
I am doing something wrong?
Does anybody knows a better solution to do this?
Fetch may not support Blob and FormData at this moment, but you can use XMLHttpRequest polyfill instead.
let xhr = new XMLHttpRequest()
xhr.open('post', `http://myserver.com/upload-form`)
xhr.send(form)
xhr.onerror = function(e) {
console.log('err', e)
}
xhr.onreadystatechange = function() {
if(this.readyState === this.DONE) {
console.log(this.response)
}
}

Categories

Resources