getdownloadurl from Firebase storage expo cli - react-native

I am trying to display the image from firebase storage. Below is the file location copied from firebase storage. It is a jpeg file
profile/2186uPKjgo4pMOQNm0Cm/profilepic
My following code returned error.
useEffect(() => {
function geturl(){
const filename = "profile/"+userid+"/profilepic.jpeg";
var ref = firebase.storage().ref(filename);
console.log(filename);
// This returns the exact file name
ref.getDownloadURL().then((url)=> {
console.log(url);
});
}
geturl();
}, []);
I got this error [object Object]. After that, I tried the following code async await
useEffect(() => {
async function geturl(){
const filename = "profile/"+userid+"/profilepic.jpeg";
var ref = firebase.storage().ref(filename);
console.log("inside geturl");
const downloadurl = await ref.getDownloadURL();
console.log(downloadurl);
}
geturl();
}, []);
Now Im getting the following error.
Possible Unhandled Promise Rejection (id: 29):
"code_": "storage/object-not-found",
"message_": "Firebase Storage: Object 'profile/2186uPKjgo4pMOQNm0Cm/profilepic.jpeg' does not exist.",
"name_": "FirebaseError",
"serverResponse_": "{
\"error\": {
\"code\": 404,
\"message\": \"Not Found. Could not get object\",
\"status\": \"GET_OBJECT\"
}
}",
}
Please let me know how I can get the url?

here you go you can use this function it uploads image to firebase storage and get the image uri at the same time
const uploadImage = async () => {
const response = await fetch(image);
const blob = await response.blob();
let filename = image.substring(image.lastIndexOf('/')+1);
const ext = filename.split('.').pop();
const name = filename.split('.').slice(0, -1).join('.');
filename = name + Date.now() + '.' + ext;
try {
var ref = firebase.storage().ref().child('post-images/'+filename);
await ref.put(blob)
.then(snapshot => {
return snapshot.ref.getDownloadURL();
})
.then(downloadURL => {
console.log(`Successfully uploaded file and got download link');
return downloadURL;
});
return null;
} catch (error) {
return null;
}
}

Related

How to save .DOC file with expo-file-system in react-native?

I'm having trouble saving a .DOC file using expo-file-system.
I'm getting the following feedback:
[Unhandled promise rejection: Error: Invalid argument "localUri". It
must be a string!]
This is my current code:
useEffect(() => {
const saveFile = async () => {
const { granted } = await Notifications
.requestPermissionsAsync()
.then((response) => response)
.catch((error) => error);
console.log(granted);
if (granted) {
data.map(async (index) => {
const date = new Date(index.synchronization)
const formattedDate = date.toISOString().split('T')[0];
const fileUri = `${FileSystem.documentDirectory}${formattedDate}.doc`;
console.log(fileUri)
await FileSystem.writeAsStringAsync(
fileUri,
"Hello World, i'am saving this file :)",
{
encoding: FileSystem.EncodingType.UTF8
});
const asset = await MediaLibrary.createAssetAsync(`${fileUri}`);
await MediaLibrary.createAssetAsync(asset);
console.log(asset);
});
}
}
saveFile();
}, [data]);
The error is probably occurring on this line:
const asset = await MediaLibrary.createAssetAsync(`${fileUri}`);
await MediaLibrary.createAssetAsync(asset);
Okay, I did!
It's a boring prank these promises
const { uri } = await MediaLibrary
.createAssetAsync(`${fileUri}`)
.then((response) => response)
.catch((error) => error);;
await MediaLibrary.createAssetAsync(uri);
Necessita do uso de then and catch

MERN and Amazon-s3 for file upload

How to post a file to Amazon S3 using node and react and save it path to mongoDB. with mongoose and formidable.
private async storeFile(file: { buffer: Buffer, fileId: string }): Promise<string> {
try {
const awsConfig = new AWS.Config(storageConfig);
const s3 = new AWS.S3(awsConfig);
let storageLink = undefined;
fs.readFile(file.buffer, (err, data) => {
if (err) {
throw err;
}
const params = {
Bucket:storageConfig.s3Bucket,
Key: `${storageConfig.s3Prefix}${file.fileId}`,
Body: data,
};
s3.upload(params, (s3Err: Error, s3Data: AWS.S3.ManagedUpload.SendData) => {
if (s3Err) {
throw s3Err;
}
storageLink = s3Data.Location;
});
});
return storageLink;
} catch (error) {
throw error;
}
}
In your Service file where you wanna call this function, update with record in collection
const storageLink = this.storeFile({ buffer, fileId });
const file = await file.updateOne({ _id: fileId }, {
status: fileStatus.UPLOADED, // just a flag
fileId: storageLink,
});

#react-native-firebase/storage - get url after uploading an image

Im trying to find an efficient way to get the url of an image in firebase right after ive uploaded it.
Id like to avoid writing a totally separate function to this....and instead Id like to include it in the promise chain. See code below
import storage from '#react-native-firebase/storage';
storage()
.ref('path/to/remote/folder')
.putFile('uri/of/local/image')
.then(() => {
//Id like to use getDownloadUrl() function here;
})
You can create chain of promises using await and then easily get your download url as below :
/**
* Upload the image to the specific firebase path
* #param {String} uri Uri of the image
* #param {String} name Name of the image
* #param {String} firebasePath Firebase image path to store
*/
const uploadImage = async (uri, name, firebasePath) => {
const imageRef = storage().ref(`${firebasePath}/${name}`)
await imageRef.putFile(uri, { contentType: 'image/jpg'}).catch((error) => { throw error })
const url = await imageRef.getDownloadURL().catch((error) => { throw error });
return url
}
Now you can call this function as below :
const uploadedUrl = await uploadImage('uri/of/local/image', 'imageName.jpg', 'path/to/remote/folder');
Now uploadedUrl will contains url of the uploaded image.
Good answer from Kishan but did not work for me....below includes some minor modifications so would work for me.
const localUri = Platform.OS === 'ios' ? imgPickResponse.uri.replace('file://', '') : imgPickResponse.uri;
this.uploadImageAndGetUrl(localUri, '/profilePics/' + this.props.userId)
.then(url => {console.log(url);});
}
uploadImageAndGetUrl = async (localUri, firebasePath) => {
try {
const imageRef = storage().ref(firebasePath);
await imageRef.putFile(localUri, {contentType: 'image/jpg'});
const url = await imageRef.getDownloadURL();
return url;
} catch (err) {
Alert.alert(err);
}
};
In my case, uri threw an error with Android permissions. So following function worked for me. Instead of uri, I passed response.path from the ImagePicker. Tip: you can use uuid to generate random file name.
this.uploadAndReturnFirestoreLink(response.path, 'images/' + 'example.jpg')
uploadAndReturnFirestoreLink = async (loaclPath, folderPath) => {
console.log(loaclPath)
try {
const imageRef = storage().ref(folderPath);
await imageRef.putFile(loaclPath, { contentType: 'image/jpg' });
const url = await imageRef.getDownloadURL();
console.log(url)
alert('Upload Success', url)
} catch (e) {
console.log(e);
}
};

How to upload image to firebase using react native

I need way to upload image to firebase
i tried to use react-native-fetch-blob library
but I think there is something wrong with installing the library
No need to use react-native-fetch-blob. Here is how I do it on my project.
Install both react-native-firebase and react-native-image-picker. Follow the installation steps from their documentation guide.
Then implement 2 small functions to do image pick and upload to firebase. Here is the sample code.
// 1. Import required library
import firebase from 'react-native-firebase';
import ImagePicker from 'react-native-image-picker';
// 2. Create a function to pick the image
const pickImage = () => {
return new Promise((resolve, reject) => {
ImagePicker.showImagePicker(pickerOptions, response => {
if (response.didCancel) return;
if (response.error) {
const message = `An error was occurred: ${response.error}`;
reject(new Error(message));
return;
}
const { path: uri } = response;
resolve(uri);
});
});
};
// 3. Create a function to upload to firebase
const uploadImage = async (fileName, uri) {
return new Promise(
(resolve, reject) => {
firebase
.storage()
.ref(`uploads/${filename}`)
.putFile(uri)
.then(resolve)
.catch(reject);
}
);
}
Then simply firing both function as you need, here is the sample to pick and immediately upload it.
const pickImageAndUpload = async () => {
const uri = await pickImage();
const fileName = 'someImage.jpg';
const { state, downloadURL } = await uploadImage(fileName, uri);
}
async function uploadImageAsync(itemImage, passedParameter, ItemName, ItemDesc, ItemPrice, ItemWeight) {
const response = await fetch(itemImage);
const blob = await response.blob();
console.log("uri of the elements ius", blob)
var storageRef = firebase.storage().ref();
var file = blob
var metadata = {
contentType: 'image/jpeg',
};
const timeStamp = Date.now();
var uploadTask = storageRef.child('CategoryDescription' + "/" + `${passedParameter}` + "/" + `${ItemName}`).put(file, metadata);
//For image pick
pickImage = async () => {
const { CAMERA, CAMERA_ROLL } = Permissions;
const permissions = {
[CAMERA]: await Permissions.askAsync(CAMERA),
[CAMERA_ROLL]: await Permissions.askAsync(CAMERA_ROLL),
};
if (permissions[CAMERA].status === 'granted' && permissions[CAMERA_ROLL].status === 'granted') {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: false,
aspect:[4,3],
quality: 0.5,
});
// console.log(result);
if (!result.cancelled) {
this.setState({ itemImage: result.uri });
}
}

GCloud Function & GStorage: sending downloaded file error: 'write after end'

My goal is to retrieve a file from Google Storage and then send it back via response. The problem is that, when I launch this function for the first time it crashes with Error [ERR_STREAM_WRITE_AFTER_END]: write after end. The next executions work fine.
exports = module.exports = region(defaultRegion).https.onRequest(async (req, res): Promise<void> => {
const [authError] = await to(handleAuth(req, res));
if (authError) {
res.status(500).send(authError.message);
return;
}
const { assetId, contentType, path } = req.query;
const file = bloqifyStorage.bucket().file(`assets/${assetId}/${path}`);
const fileExists = (await file.exists())[0];
if (!fileExists) {
res.status(404).send(`${path} was not found`);
return;
}
const fileStream = file.createReadStream();
fileStream.pipe(res).on('end', (): void => {
res.setHeader('content-type', contentType);
});
});
What am I missing here?
Edit: removing the set header doesn't solve it. Ex:
const fileStream = file.createReadStream();
// res.setHeader('content-type', contentType);
fileStream.pipe(res).on('error', (e): void => {
console.log(e);
});
It will print the same error.