I'm trying to delete an image from Firebase storage in React Native by downloadURL. Also i'm using web V9.
Writing down most essential chuncks of code:
import {
deleteObject,
getStorage,
ref
} from "firebase/storage";
...
// DownloadURL
const photo = "https://firebasestorage.googleapis.com.... ";
const storage = getStorage();
...
const storageRef = ref(storage, photo);
deleteObject(storageRef)
.then(() => {
console.log("File deleted successfully");
})
.catch((error) => {
console.log(error.message);
});
My code is inspired from here and I got this error:
[Unhandled promise rejection: FirebaseError: Firebase Storage: The
operation 'deleteObject' cannot be performed on a root reference,
create a non-root reference using child, such as .child('file.png').
(storage/invalid-root-operation)]
I'm little confused.
Later edit:
My function which upload the image and get the download url:
// uri is returned from "expo-image-picker"
const uploadImageAsync = async (uri) => {
// manipulateAsync imported from 'expo-image-manipulator'
const manipResult = await manipulateAsync(uri, [], {
compress: 0.6,
format: "jpeg",
});
const response = await fetch(manipResult.uri);
const blob = await response.blob();
const imageName = Date.now().toString();
const fileRef = ref(storage, `avatar/${user.uid}/${imageName}.jpg`);
const result = await uploadBytes(fileRef, blob);
getDownloadURL(fileRef).then((snapshot) => {
// downloadURL is added to Redux state to be used later
dispatch(addPhoto(snapshot));
});
};
Related
I have a problem deleting my entire folder on firebase storage. I always get a 'storageRef.listAll is not a function' error when I specify the reference to the path. I would like to delete the complete path with all possibly existing images.
const storage = getStorage();
const storageRef = ref(
storage,
`${aktuellerUser._id}/artikelBilder/`
);
storageRef
.listAll()
.then((listResults) => {
const promises = listResults.items.map((item) => {
return item.delete();
});
Promise.all(promises);
})
.catch((error) => {
console.log(error);
});
error TypeError: storageRef.listAll is not a function
You are using the new Firebase Modular SDK where listAll() is a top level function and not a method on StorageReference. Similarly, you need to use deleteObject() to delete a file now instead of .delete() method as shown below:
import {
getStorage,
ref,
listAll,
deleteObject
} from "firebase/storage";
listAll(storageRef)
.then(async (listResults) => {
const promises = listResults.items.map((item) => {
return deleteObject(item);
});
await Promise.all(promises);
})
I'm trying to accomplish the following task: I need to download image from url, then upload it to S3 storage and return the location of the uploaded file. I'm using async/await functions to do the task, but it returns Promise { pending } and after few seconds returns the location, i want to return location after promise is resolved. Here is my code:
// Space config
const spaceEndPoint = new AWS.Endpoint("fra1.digitaloceanspaces.com");
const s3 = new AWS.S3({
endpoint: spaceEndPoint,
accessKeyId: "xxxxxxxxx",
secretAccessKey: "xxxxxxxxxxxxxxxxx",
});
// Download image from url
const downloadImage = async (url) => {
try {
const file = axios
.get(url, {
responseType: "stream",
})
.then((res) => res.data)
.catch((err) => console.log(err));
return file;
} catch (err) {
console.log(err);
}
};
// Upload to space
const upload = async (fileUrl) => {
// Get file name from url
const fileName = path.basename(fileUrl);
// Path to save tmp file
const localFilePath = path.resolve(__dirname, "../downloads", fileName);
// Download file
const file = await downloadImage(fileUrl);
// Write file to disk
await file.pipe(fs.createWriteStream(localFilePath));
// Upload params
const params = {
Bucket: "sunday",
Body: fs.createReadStream(localFilePath),
Key: path.basename(fileName),
ContentType: "application/octet-stream",
ACL: "public-read",
};
const { Location } = await s3.upload(params).promise();
return Location;
};
console.log(
upload(
"https://i.pinimg.com/474x/e9/62/7c/e9627ce6fe731ba49597d3a83e21e398.jpg"
).then((data) => data)
);
// Result:
Promise { <pending> }
https://sunday.fra1.digitaloceanspaces.com/e9627ce6fe731ba49597d3a83e21e398.jpg
So i want to return location when promise is resolved.
Thanks in advance for help!
Your function upload is async and thus always returns a promise that should be awaited too. await your upload call. If you're in environment that doesn't support top level await, use .then to log results instead or put outer logging code in helper function.
I am trying to upload an image to a cloud storage and received an post 400 error
The file is in initialize in another component.
Thanks for help
const projectStorage = getStorage();
useEffect(() => {
const storageRef = ref(projectStorage, file.name);
uploadBytes(storageRef, file).then((snap) => {
let percentage = (snap.bytesTransferred / snap.totalBytes) * 100;
setProgress(percentage);
console.log('File Uploaded');
}, (err) => {
setError(err);
}, async () => {
//this url doesnt change the setstate url becuase it is in seperate score
const url = await storageRef.getDownloadURL();
setUrl(url);
})
}, [file]);
I created a new project on firebase and then change the permissions on the storage rules and its works.
i have a bunch of VHD files stored on a private Server, which are accessible through a url.
I am trying upload these vhd files directly to my azure storage account using the azure javascript npm libraries. The vhds have to be uploaded as page-blobs. I tried using the method uploadPagesFromURL() of the pageblobClient but with no success. My code looks roughly like this:
async function uploadVHD(accessToken, srcUrl)
{
try {
// Get credentials from accessToken
const creds = new StorageSharedKeyCredential(storageAccount.name, storageAccount.key);
// Get blobServiceClient
const blobServiceClient = new BlobServiceClient(`https://${storageAccount.name}.blob.core.windows.net`, creds);
// Create Container
const containerClient = blobServiceClient.getContainerClient("vhd-images");
await containerClient.createIfNotExists();
const src = srcUrl.replace('https://', 'https://username:password#');
// Upload to blob storage
const pageBlobClient = containerClient.getPageBlobClient("Test.vhd");
// Get fileSize of vhd
const fileSize = (await axiosRequest(src, { method: "HEAD" })).headers["content-length"];
const uploadResponse = await pageBlobClient.uploadPagesFromURL(src, 0, 0, fileSize);
return uploadResponse;
} catch (error) {
return error;
}
});
It is not possible to upload the Page Blob with your URL directly. You need to read data from the url. Then upload using uploadPages method.
axios.get(URL, {
responseType: 'arraybuffer'
})
.then((response) => {
console.log(response.data)
console.log(response.data.length)
// upload page blob...
}).catch((error) => {
//handle error
});
// uploadPages method
const uploadResponse = pageBlobClient.uploadPages(data, 0, dataLength);
I am trying to read the csv file inside the Firebase functions so that i can send the mail to the all the records. I am planning to go with the following procedure
upload the csv
fire a on finalize function
read the file and send emails
Below is the function
import * as functions from "firebase-functions";
import * as mkdirp from "mkdirp-promise";
import * as os from "os";
import * as path from "path";
import csv = require('csvtojson');
const gcs = require('#google-cloud/storage')({ keyFilename: 'service-account-credentials.json' });
const csvDirectory = "csv";
export = functions.storage.object().onFinalize(async (object) => {
const filePath = object.name;
const contentType = object.contentType;
const fileDir = path.dirname(filePath);
if(fileDir.startsWith(csvDirectory) && contentType.startsWith("text/csv")) {
const bucket = gcs.bucket(object.bucket);
const file = bucket.file(filePath);
const fileName = path.basename(filePath);
const tempLocalFile = path.join(os.tmpdir(), filePath);
const tempLocalDir = path.dirname(tempLocalFile);
console.log("values", bucket, file, fileName, tempLocalDir, tempLocalFile);
console.log("csv file uploadedeeeed");
await mkdirp(tempLocalDir);
await bucket.file(filePath).download({
destination: tempLocalFile
});
console.log('The file has been downloaded to', tempLocalFile);
csv()
.fromFile(tempLocalFile)
.then((jsonObj) => {
console.log(jsonObj);
})
}
});
While running the code i am only getting csv file uploadeded which i have written inside the console.log and then i get the timeout after 1 minute .i am also not getting the The file has been downloaded to log . Can anybody look at the code and help me to get out of this.
You are mixing up the use of async/await together with a call to then() method. You should also use await for the fromFile() method.
The following should do the trick (untested):
export = functions.storage.object().onFinalize(async (object) => {
const filePath = object.name;
const contentType = object.contentType;
const fileDir = path.dirname(filePath);
try {
if (fileDir.startsWith(csvDirectory) && contentType.startsWith("text/csv")) {
//.....
await mkdirp(tempLocalDir);
await bucket.file(filePath).download({
destination: tempLocalFile
});
console.log('The file has been downloaded to', tempLocalFile);
const jsonObj = await csv().fromFile(tempLocalFile);
console.log(jsonObj);
return null;
} else {
//E.g. throw an error
}
} catch (error) {
//.....
}
});
Also note that (independently of the mixed use of async/await and then()), with the following line in your code
csv().fromFile(tempLocalFile).then(...)
you were not returning the Promise returned by the fromFile() method. This is a key point in Cloud Functions.
I would suggest you watch the official Video Series on Cloud Functions (https://firebase.google.com/docs/functions/video-series/) and in particular the videos on Promises titled "Learn JavaScript Promises".