Cloud Storage getDownloadURL() - react-native

I am trying to retrieve downloadable URL of images in my Firestore database. This is my code:
var storageRef = firebase.storage().ref();
storageRef
.child(`tutorials/images/${filename}`)
.getDownloadURL()
.then(function(url) {
this.setState({ imgURL: url });
console.log(url);
})
.catch(function(error) {
console.warn(error);
});
but I get a error RNFIrebaseStoragepromiseRejectStorageException error. Anyone have a solution to how I can successfully retrieve the downloadable URL from the Firestore? Thanks.

Things to try:
Try to download a hardcoded URL, just to be sure the path exists
Double check your storage permissions.

Related

Google cloud storage on react native

I have a project needs to store profile photos on google cloud storage. I got a signed URL from our API, and I upload the image with:
const xhr = new XMLHttpRequest();
xhr.open("PUT", signedURL, true);
xhr.onload = () => {
const status = xhr.status;
if (status === 200) {
console.log("ok");
} else {
console.log("Something went wrong!", status);
}
};
xhr.onerror = () => {
console.log("......Something went wrong!")
};
xhr.setRequestHeader('Content-Type', "application/octet-stream");
const fileBuffer = base64.toByteArray(data)
xhr.send(fileBuffer);
To render image on React Native, I am using in this way:
<Image source={{uri: 'https://storage.googleapis.com/mybucketname/myfile.jpg'}} />,
I changed the bucket to Public Access (add member allUsers to Storage Object Viewer).
The result is, from the dashboard, I click Public to internet and Link URL, they return two different images, which Public to internet always the first image and Link URL is always the latest uploaded. Any idea how to fix this or what is the correct way to show the image?
Besides, I also need to upload and review videos and documents, is that possible to render on react native, even if the bucket has to be private?

Is it possible to get the binary data from an image in React-Native?

I'm using react-native-camera and I'm having trouble getting the image as binary data in react-native. I need this to be able to upload images to our backend. The only thing I manage to get is uri's to the image and then maybe sending that as FormData to the server but that is not recommended as that would require some infrastructure change to our backend.
Is there anyone that know a solution or some tips regarding this issue?
Any thoughts or help is very much appreciated.
If you want to get image as binary data from react-native-camera. I recommend to use react-native-fs to read uri
Example
const RNFS = require("react-native-fs");
// response.uri from react-native-camera
RNFS.readFile(response.uri, "base64").then(data => {
// binary data
console.log(data);
});
If you want to upload image via FormData I recommend rn-fetch-blob
Example
import RNFetchBlob from 'rn-fetch-blob'
// response.uri from react-native-camera
const path = response.uri.replace("file://", "");
const formData = [];
formData.push({
name: "photo",
filename: `photo.jpg`,
data: RNFetchBlob.wrap(path)
});
let response = await RNFetchBlob.fetch(
"POST",
"https://localhost/upload",
{
Accept: "application/json",
"Content-Type": "multipart/form-data"
},
formData
);
An alternative if you're already using react-native-camera is upon capturing the image, you request it as base64 directly as such:
takePicture = async function(camera) {
const options = { quality: 0.5, base64: true, doNotSave: true }
const data = await camera.takePictureAsync(options)
console.log(data.base64)
}
If your goal is to only snap the picture, show a preview perhaps then upload to the server and move on, then the benefit of this approach is that it won't save that photo in your device cache (doNotSave: true). Which means that you don't need to worry about cleaning those up after you're done.
You can use 'react-native-image-crop-picker' to pick image and video. Set following property to true
includeBase64: true
and image file content will be available as a base64-encoded string in the data property
ImagePicker.openPicker({
mediaType: "photo",
includeBase64: true // this will give 'data' in response
})
.then((response) => {
console.log(resonse.data)
})
.catch((error) => {
alert(error)
});

Proper React Native "file" for Cloudinary API image upload?

http://cloudinary.com/documentation/image_upload_api_reference#upload
I tried the following:
user picks from camera roll:
{
data: "/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZg..."
origURL: "assets-library://asset/asset.JPG?id=ED7AC36B-A150-4C38-BB8C-B6D696F4F2ED&ext=JPG",
uri: "file:///Users/me/Library/Developer/CoreSimulator/Devices/1BC4A449-46CF-4ADE-A9B5-78906C9C50FB..."
}
then on the server (Node.js), I am trying to use uri from above:
addUserPhoto(uri) {
const photo = new Promise((resolve, reject) => {
const base64URI = new Buffer(uri).toString('base64');
cloudinary.v2.uploader.upload('data:image/jpeg;base64,'+base64URI, {}, (result) => {
console.log(result);
resolve(result);
});
});
return photo;
}
But I get the error:
{ message: 'Invalid image file', http_code: 400 }
Am not sure about the correct "file". What am I doing wrong? Which field am I supposed to pick from the camera roll data, and how do I convert it to a compatible "file" for Cloudinary API?
The uri is the local filepath to your image (on the phone), so the server doesn't have access to it.
The way to send an image to a distant host is to send the data.
So it ended up being the data one. Like this:
data:image/jpeg;base64,/9j/4AAQSkZ...
After that, Node Express was giving me Error: request entity too large (so I thought it was still wrong)
Turns out I had to do:
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));

How to upload file to server using react-native

I am developing a app where i need to upload an image to the server. Based on the image i get a response which i need to render?.
Can you please help me how to upload an image using react-native?.
There is file uploading built into React Native.
Example from React Native code:
var photo = {
uri: uriFromCameraRoll,
type: 'image/jpeg',
name: 'photo.jpg',
};
var body = new FormData();
body.append('authToken', 'secret');
body.append('photo', photo);
body.append('title', 'A beautiful photo!');
var xhr = new XMLHttpRequest();
xhr.open('POST', serverURL);
xhr.send(body);
My solution is using fetch API and FormData.
Tested on Android.
const file = {
uri, // e.g. 'file:///path/to/file/image123.jpg'
name, // e.g. 'image123.jpg',
type // e.g. 'image/jpg'
}
const body = new FormData()
body.append('file', file)
fetch(url, {
method: 'POST',
body
})
I wrote something like that. Check out https://github.com/kamilkp/react-native-file-transfer
I have been struggling to upload images recently on react-native. I didn't seem to get the images uploaded. This is actually because i was using the react-native-debugger and network inspect on while sending the requests. Immediately i switch off network inspect, the request were successful and the files uploaded.
I am using the example from this answer above it works for me.
This article on github about the limitations of network inspect feature may clear things for you.
Just to build on the answer by Dev1, this is a good way to upload files from react native if you also want to show upload progress. It's pure JS, so this would actually work on any Javascript file.
(Note that in step #4 you have to replace the variables inside the strings with the type and file endings. That said, you could just take those fields out.)
Here's a gist I made on Github: https://gist.github.com/nandorojo/c641c176a053a9ab43462c6da1553a1b
1. for uploading one file:
// 1. initialize request
const xhr = new XMLHttpRequest();
// 2. open request
xhr.open('POST', uploadUrl);
// 3. set up callback for request
xhr.onload = () => {
const response = JSON.parse(xhr.response);
console.log(response);
// ... do something with the successful response
};
// 4. catch for request error
xhr.onerror = e => {
console.log(e, 'upload failed');
};
// 4. catch for request timeout
xhr.ontimeout = e => {
console.log(e, 'cloudinary timeout');
};
// 4. create formData to upload
const formData = new FormData();
formData.append('file', {
uri: 'some-file-path', // this is the path to your file. see Expo ImagePicker or React Native ImagePicker
type: `${type}/${fileEnding}`, // example: image/jpg
name: `upload.${fileEnding}` // example: upload.jpg
});
// 6. upload the request
xhr.send(formData);
// 7. track upload progress
if (xhr.upload) {
// track the upload progress
xhr.upload.onprogress = ({ total, loaded }) => {
const uploadProgress = (loaded / total);
console.log(uploadProgress);
};
}
2. uploading multiple files
Assuming you have an array of files you want to upload, you'd just change #4 from the code above to look like this:
// 4. create formData to upload
const arrayOfFilesToUpload = [
// ...
];
const formData = new FormData();
arrayOfFilesToUpload.forEach(file => {
formData.append('file', {
uri: file.uri, // this is the path to your file. see Expo ImagePicker or React Native ImagePicker
type: `${type}/${fileEnding}`, // example: image/jpg
name: `upload.${fileEnding}` // example: upload.jpg
});
})
In my opinion, the best way to send the file to the server is to use react-native-fs package, so install the package
with the following command
npm install react-native-fs
then create a file called file.service.js and modify it as follow:
import { uploadFiles } from "react-native-fs";
export async function sendFileToServer(files) {
return uploadFiles({
toUrl: `http://xxx/YOUR_URL`,
files: files,
method: "POST",
headers: { Accept: "application/json" },
begin: () => {
// console.log('File Uploading Started...')
},
progress: ({ totalBytesSent, totalBytesExpectedToSend }) => {
// console.log({ totalBytesSent, totalBytesExpectedToSend })
},
})
.promise.then(({ body }) => {
// Response Here...
// const data = JSON.parse(body); => You can access to body here....
})
.catch(_ => {
// console.log('Error')
})
}
NOTE: do not forget to change the URL.
NOTE: You can use this service to send any file to the server.
then call that service like the following:
var files = [{ name: "xx", filename:"xx", filepath: "xx", filetype: "xx" }];
await sendFileToServer(files)
NOTE: each object must have name,filename,filepath,filetype
A couple of potential alternatives are available. Firstly, you could use the XHR polyfill:
http://facebook.github.io/react-native/docs/network.html
Secondly, just ask the question: how would I upload a file in Obj-C? Answer that and then you could just implement a native module to call it from JavaScript.
There's some further discussion on all of this on this Github issue.
Tom's answer didn't work for me. So I implemented a native FilePickerModule which helps me choose the file and then use the remobile's react-native-file-transfer package to upload it. FilePickerModule returns the path of the selected file (FileURL) which is used by react-native-file-transfer to upload it.
Here's the code:
var FileTransfer = require('#remobile/react-native-file-transfer');
var FilePickerModule = NativeModules.FilePickerModule;
var that = this;
var fileTransfer = new FileTransfer();
FilePickerModule.chooseFile()
.then(function(fileURL){
var options = {};
options.fileKey = 'file';
options.fileName = fileURL.substr(fileURL.lastIndexOf('/')+1);
options.mimeType = 'text/plain';
var headers = {
'X-XSRF-TOKEN':that.state.token
};
options.headers = headers;
var url = "Set the URL here" ;
fileTransfer.upload(fileURL, encodeURI(url),(result)=>
{
console.log(result);
}, (error)=>{
console.log(error);
}, options);
})
Upload Files : using expo-image-picker npm module. Here we can upload any files or images etc. The files in a device can be accessed using the launchImageLibrary method. Then access the media on that device.
import * as ImagePicker from "expo-image-picker";
const loadFile = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
aspect: [4, 3],
});
return <Button title="Pick an image from camera roll" onPress={loadFile} />
}
The above code used to access the files on a device.
Also, use the camera to capture the image/video to upload by using
launchCameraAsync with mediaTypeOptions to videos or photos.

quickblox web how to upload profile picture

I'm trying to upload a profile picture (blob_id) from a javascript document and I can't find a way, I donĀ“t know if I should use this snippets or even how to use it :(
I'll be so thankfull if you could help me
Thanks
QB.users.update({ id: user_creds.user_id, website: "http://quickblox.com"}, function(error, response){
if(error) {
console.log(error);
} else {
// Success
}
});
sorry about this. We'll be beefing up the documentation soon.
Here's how to upload a profile picture
We'll have a file input:
<input type="file" id="picture" />
Then assuming you have jQuery in your environment, we'll reference it like this:
var profile_picture = $("#picture")[0].files;
Then you upload the file to Quickblox AWS like so:
QB.content.createAndUpload({file: profile_picture, public: true}, function(error, response) {
if (error) {
console.log("upload didn't work");
} else {
var blob_id = response.id;
}
});
As you can see, the ID of the blob is the id field of the response.
You then add this blob ID as the blob_id field of a new user when you create him/her:
QB.users.create({login: "username_here", password: "password_here", blob_id: blob_id_here}, function(error, response){
if(error) {
console.log(error);
} else {
}
});
I made a page which demos the uploading functionality of the Javascript SDK - you can check it out here: http://www.quickblox.com/alex/websdk/upload.html