Im using firebase storage, while uploading images to it i also pass in cacheControl pair. Im having trouble on getting the image to cache locally when i download.
Any help pls ..
doupload(event: FileList) {
const file = event.item(0);
if (file.type.split('/')[0] !== 'image') {
console.error('unsupported file type:(');
return;
}
const path = `test/${new Date().getTime()}_${file.name}`;
const fileRef = this.storage.ref(path);
const customMetadata = { app: 'Namma Tiruppur', cacheControl: 'public,max-age=150000', };
this.task = this.storage.upload(path, file, { customMetadata });
this.percentage = this.task.percentageChanges();
this.snapshot = this.task.snapshotChanges().pipe(
tap(snap => {
if (snap.bytesTransferred === snap.totalBytes) {
this.newsImg = path;
}
})
);
this.snapshot.pipe(finalize(() => this.downloadURL = fileRef.getDownloadURL())).subscribe();
}
Related
i am trying to make a component that take a pdf from input or an already uploaded one and then extract pages from it and uploaded again
when choosing a file from input (choosing file from my computer)
i am using this
const handleFileChange = async (event) => {
const file = event.target.files[0];
setFiles(event.target.files[0])
const fileName = event.target.files[0].name
setFileName(fileName);
const fileReader = new FileReader();
fileReader.onload = async () => {
const pdfBytes = new Uint8Array(fileReader.result);
const pdfDoc = await PDFDocument.load(pdfBytes);
setPdfDoc(pdfDoc);
setPdfBlob(pdfBytes)
};
fileReader.readAsArrayBuffer(file);
setShowPdf(true)
};
we get a pdfDoc and a Unit8Array
then i use the pdfDoc to get pages and extract a new pdf file....
this works fine
now when selecting a file that we already uploaded
i use this to ping the api to get the file
const handleGetFile = async (url) => {
const headers = {
Authorization: "Bearer " + (localStorage.getItem("token")),
Accept: 'application/pdf'
}
await axios.put(`${process.env.NEXT_PUBLIC_API_URL}getPdfFileBlob`, {
pdfUrl: `https://handle-pdf-photos-project-through-compleated-task.s3.amazonaws.com/${url}`
}, { responseType: 'arraybuffer', headers }).then((res) => {
const handlePdf = async () => {
const uint8Array = new Uint8Array(res.data);
const pdfBlob = new Blob([uint8Array], { type: 'application/pdf' });
setPdfBlob(uint8Array)
// setPdfDoc(pdfBlob) .....? how do i create a pdf doc from the unit8array
}
handlePdf()
}).catch((err) => {
console.log(err)
})
}
this the the end point i am pinging
app.put('/getPdfFileBlob',async function(req,res){
try {
console.log(req.body.pdfUrl)
const url =req.body.pdfUrl;
const fileName = 'file.pdf';
const file = fs.createWriteStream(fileName);
https.get(url, (response) => {
response.pipe(file);
file.on('finish', () => {
file.close();
// Serve the file as a response
const pdf = fs.readFileSync(fileName);
res.setHeader('Content-Type', 'application/pdf');
res.setHeader( 'Content-Transfer-Encoding', 'Binary'
);
res.setHeader('Content-Disposition', 'inline; filename="' + fileName + '"');
res.send(pdf);
});
});
} catch (error) {
res.status(500).json({success:false,msg:"server side err"})
}
})
after getting this file here is what am trying to do
const handlePageSelection = (index) => {
setSelectedPages(prevSelectedPages => {
const newSelectedPages = [...prevSelectedPages];
const pageIndex = newSelectedPages.indexOf(index);
if (pageIndex === -1) {
newSelectedPages.push(index);
} else {
newSelectedPages.splice(pageIndex, 1);
}
return newSelectedPages;
});
};
const handleExtractPages = async () => {
for (let i = pdfDoc.getPageCount() - 1; i >= 0; i -= 1) {
if (!selectedPages.includes(i + 1)) {
pdfDoc.removePage(i);
}
}
await pdfDoc.save();
};
well in the first case where i upload the pdf file from local storage i get a pdfDoc
console of pdf Doc and pdfBlob
and when i select already existing file i can't find a way to transfer unit8array buffer to pdf doc
log of pdfBlob and no pdf doc
what i want is transform the pdfblob to pdfDcoument or get the pdf document from the array buffer so i can use getpages on it
I'm building a simple .gltf plugin for rollup.
The plugin does the following:
Load the .gltf files
Calls emitFile() for any .jpg, .png or .bin dependencies found in the .gltf
Updates the .gltf source with the URLs of the emitted .jpg, .png and .bin
Calls emitFile() for the .gltf itself
The problem is in step 3: emitFile() returns an identifier and there is no way to access the URL using getFileName() until the generation phase has finished. Which means that getFileName() is still not usable in the transform() hook. Besides, I cannot use import.meta.ROLLUP_FILE_URL_${refId} because the file I'm generating is an asset file.
The workaround I've implemented is to patch the .gltf files after the generation but this is not ideal.
What is the proper way to insert emitted file URLs inside assets?
Here's the current code:
import fs from 'node:fs';
import path from 'node:path';
import { createFilter } from '#rollup/pluginutils';
export default function gltf(options = {}) {
const filter = createFilter(options.include, options.exclude);
const exported = [];
return {
name: 'gltf',
load(id) {
if (!id.endsWith('.gltf') || !filter(id)) return null;
const basepath = path.dirname(id);
const source = fs.readFileSync(id);
try {
const model = JSON.parse(source.toString());
const assets = {};
if (model.images) {
model.images.forEach(image => {
const ref = this.emitFile({
type: 'asset',
name: path.basename(image.uri),
source: fs.readFileSync(path.join(basepath, image.uri))
});
assets[image.uri] = ref;
// image.uri = 'import.meta.ROLLUP_FILE_URL_' + ref;
});
}
if (model.buffers) {
model.buffers.forEach(buffer => {
const ref = this.emitFile({
type: 'asset',
name: path.basename(buffer.uri),
source: fs.readFileSync(path.join(basepath, buffer.uri))
});
assets[buffer.uri] = ref;
// buffer.uri = 'import.meta.ROLLUP_FILE_URL_' + ref;
});
}
const ref = this.emitFile({
type: 'asset',
name: path.basename(id),
// source: JSON.stringify(model)
source
});
exported.push({ ref, assets });
return `export default import.meta.ROLLUP_FILE_URL_${ref};`;
} catch (err) {
this.error(err);
}
},
writeBundle(options) {
const done = new Set(); // keep track of the files already patched
exported.forEach(entry => {
const filename = this.getFileName(entry.ref);
if (done.has(filename)) return;
done.add(filename);
const filepath = path.join(options.dir, filename);
const source = fs.readFileSync(filepath);
try {
const model = JSON.parse(source);
if (model.images) {
model.images.forEach(image => {
const ref = entry.assets[image.uri];
if (ref) {
image.uri = path.basename(this.getFileName(ref));
}
});
}
if (model.buffers) {
model.buffers.forEach(buffer => {
const ref = entry.assets[buffer.uri];
if (ref) {
buffer.uri = path.basename(this.getFileName(ref));
}
});
}
fs.writeFileSync(filepath, JSON.stringify(model));
} catch (err) {
this.error(err);
}
});
}
}
}
I am trying to upload Image using Firebase in Firebase Storage, but file doesn't uploads completely. It shows the size of image 9 bytes only, and when downloaded, it can't be previewed.
Here is the code i am using:-
const [image, setImage] = useState(null)
const [uploading, setUploading] = useState(false);
const [transferred, setTransferred] = useState(0);
const uploadImage = async () => {
if( image == null ) {
return null;
}
const uploadUri = image;
let filename = uploadUri.substring(uploadUri.lastIndexOf('/') + 1);
console.log(filename)
// Add timestamp to File Name
const extension = filename.split('.').pop();
const name = filename.split('.').slice(0, -1).join('.');
filename = name + Date.now() + '.' + extension;
console.log("filename")
console.log(filename)
setTransferred(0);
const storageRef = firebase.storage().ref(`photos/${filename}`);
console.log("storageRef")
const task = storageRef.put(uploadUri);
console.log("storageRef")
console.log(storageRef)
// Set transferred state
task.on('state_changed', (taskSnapshot) => {
console.log(
`${taskSnapshot.bytesTransferred} transferred out of ${taskSnapshot.totalBytes}`,
);
setTransferred(
Math.round(taskSnapshot.bytesTransferred / taskSnapshot.totalBytes) *
100,
);
console.log(transferred)
});
try {
await task;
const url = await storageRef.getDownloadURL();
setUploading(false);
setImage(null);
alert(
'Image uploaded!',
'Your image has been uploaded to the Firebase Cloud Storage Successfully!',
);
return url;
} catch (e) {
console.log(e);
return null;
}
};
const takephotofrommlib = () => {
ImagePicker.openPicker({
width: 300,
height: 300,
cropping: true,
}).then((image) => {
console.log(image);
const imageUri = Platform.OS === 'ios' ? image.path : image.path;
setImage(image.path);
console.log("image.path")
console.log(image.path)
});
};
I am using react-native-image-crop-picker. I am using Firebase but not react-native firebase. Please Help!
i just make a file uploadFile.js
here's a code
import storage from "#react-native-firebase/storage";
export default async function uploadFile(ref,fileName,file) {
if(!file) return
const tarea=file
if (tarea&& tarea.indexOf("http://") == 0 || tarea&&tarea.indexOf("https://") == 0)
{
// do something here
return tarea
}
const reference = storage().ref(`${ref}/${fileName}`);
await reference.putFile(file).catch(err=>{console.log("error upload",err);
})
return await storage()
.ref(`${ref}/${fileName}`)
.getDownloadURL().catch(err=>{console.log("download eror",err);
});
}
you can use like this
img= await uploadFile('photos',"fileName",filePath)
In img you can get the download url
I am trying to upload an image to firebase and then produce 2 thumbnails. I am able to do this with no problems. My current road block is when I write the urls to the realtime database, I am always getting the same url as the initial upload.
For example:
1st upload I get my uploaded image with the two proper thumbnails for the image
2nd upload I get my uploaded image with the two previous thumbnails (first image)
3rd upload I get my uploaded image with the first images thumbnails...
...this continues to reproduce the urls for the first upload
In my storage the correct thumbnails are being generated, but the urls are always for the first upload?
I don't know if this is a problem with the getSignedUrl() or not, really not sure whats going on here.
Here is my cloud function:
export const generateThumbs = functions.storage
.object()
.onFinalize(async object => {
const bucket = gcs.bucket(object.bucket); // The Storage object.
// console.log(object);
console.log(object.name);
const filePath = object.name; // File path in the bucket.
const fileName = filePath.split('/').pop();
const bucketDir = dirname(filePath);
const workingDir = join(tmpdir(), 'thumbs');
const tmpFilePath = join(workingDir, 'source.png');
if (fileName.includes('thumb#') || !object.contentType.includes('image')) {
console.log('exiting function');
return false;
}
// 1. ensure thumbnail dir exists
await fs.ensureDir(workingDir);
// 2. Download Sounrce fileName
await bucket.file(filePath).download({
destination: tmpFilePath
});
//3. resize the images and define an array of upload promises
const sizes = [64, 256];
const uploadPromises = sizes.map(async size => {
const thumbName = `thumb#${size}_${fileName}`;
const thumbPath = join(workingDir, thumbName);
//Resize source image
await sharp(tmpFilePath)
.resize(size, size)
.toFile(thumbPath);
//upload to gcs
return bucket.upload(thumbPath, {
destination: join(bucketDir, thumbName),
metadata: {
contentType: 'image/jpeg'
}
}).then((data) => {
const file = data[0]
// console.log(data)
file.getSignedUrl({
action: 'read',
expires: '03-17-2100'
}).then((response) => {
const url = response[0];
if (size === 64) {
// console.log('generated 64');
return admin.database().ref('profileThumbs').child(fileName).set({ thumb: url });
} else {
// console.log('generated 128');
return admin.database().ref('categories').child(fileName).child('thumb').set(url);
}
})
.catch(function (error) {
console.error(err);
return;
});
})
});
//4. Run the upload operations
await Promise.all(uploadPromises);
//5. Cleanup remove the tmp/thumbs from the filesystem
return fs.remove(workingDir);
})
Cleaned up my code and solved my problem, here is how I generated the urls and passed them to the proper URLs by accessing the users UID and postId in the file path:
export const generateThumbs = functions.storage
.object()
.onFinalize(async object => {
const fileBucket = object.bucket; // The Storage bucket that contains the file.
const filePath = object.name; // File path in the bucket.
const fileName = filePath.split('/').pop();
const userUid = filePath.split('/')[2];
const sizes = [64, 256];
const bucketDir = dirname(filePath);
console.log(userUid);
if (fileName.includes('thumb#') || !object.contentType.includes('image')) {
console.log('exiting function');
return false;
}
const bucket = gcs.bucket(fileBucket);
const tempFilePath = path.join(tmpdir(), fileName);
return bucket.file(filePath).download({
destination: tempFilePath
}).then(() => {
sizes.map(size => {
const newFileName = `thumb#${size}_${fileName}.png`
const newFileTemp = path.join(tmpdir(), newFileName);
const newFilePath = `thumbs/${newFileName}`
return sharp(tempFilePath)
.resize(size, size)
.toFile(newFileTemp, () => {
return bucket.upload(newFileTemp, {
destination: join(bucketDir, newFilePath),
metadata: {
contentType: 'image/jpeg'
}
}).then((data) => {
const file = data[0]
console.log(data)
file.getSignedUrl({
action: 'read',
expires: '03-17-2100'
}, function(err, url) {
console.log(url);
if (err) {
console.error(err);
return;
}
if (size === 64) {
return admin.database().ref('profileThumbs').child(userUid).child(fileName).set({ thumb: url });
} else {
return admin.database().ref('categories').child(fileName).child('thumb').set(url);
}
})
})
})
})
}).catch(error =>{
console.log(error);
});
})
I am trying to upload a single image to Firebase Storage, then grab its download url and assign this to a variable.
I can upload my image to firebase successfully, however I cannot retrieve the download url. here is what I have tried already.
upload() {
let storageRef = firebase.storage().ref();
let success = false;
for (let selectedFile of [(<HTMLInputElement>document.getElementById('file')).files[0]]) {
let router = this.router;
let af = this.af;
let folder = this.folder;
let path = `/${this.folder}/${selectedFile.name}`;
var iRef = storageRef.child(path);
iRef.put(selectedFile).then((snapshot) => {
console.log('Uploaded a blob or file! Now storing the reference at', `/${this.folder}/images/`);
af.list(`/${folder}/images/`).push({ path: path, filename: selectedFile.name })
});
}
// This part does not work
iRef.getDownloadURL().then((url) => {this.image = url});
console.log('IREF IS ' + iRef)
console.log('IMAGEURL IS ' + this.image)
}
The Console logs are these:
IREF IS gs://my-app-159520.appspot.com/images/Screen Shot 2017-08-14 at 12.19.01.png
view-order.component.ts:134 IMAGEURL IS undefined
Uploaded a blob or file! Now storing the reference at /images/images/
I have been trying to use the iRef reference to grab the download url but I keep getting errors. I am trying to grab the url so I can assign it to the this.image variable and then store it in my database using another function.
The API has changed. Use the following to get downloadURL
snapshot.ref.getDownloadURL().then(function(downloadURL) {
console.log("File available at", downloadURL);
});
I think I have figured this out and it seems to be working, I realised I had to grab the downloadURL from the snapshot and assign that to this.image like so:
upload() {
let storageRef = firebase.storage().ref();
let success = false;
for (let selectedFile of [(<HTMLInputElement>document.getElementById('file')).files[0]]) {
let router = this.router;
let af = this.af;
let folder = this.folder;
let path = `/${this.folder}/${selectedFile.name}`;
var iRef = storageRef.child(path);
iRef.put(selectedFile).then((snapshot) => {
// added this part which as grabbed the download url from the pushed snapshot
this.image = snapshot.downloadURL;
console.log('Uploaded a blob or file! Now storing the reference at', `/${this.folder}/images/`);
af.list(`/${folder}/images/`).push({ path: path, filename: selectedFile.name })
console.log('DOWNLOAD URL IS ' + this.image)
});
}
}
I then ran my other function to add the URL to the database and it has gone in ok where expected!
So I have uploaded the image to the database, then using the snapshot from the put function, I then assigned my variable image:any to to the snapshot downloadURL like so:
this.image = snapshot.downloadURL;
I hope this can help someone else!
.put() function is returning a task, which can be used to track the uploading state.
For example you can listen for progress, error or completion like so:
onUploadImage () {
const self = this
const file = self.selectedFile
if (!file) {
return
}
self.isUploading = true
const storageRef = firebase.storage().ref('/images/' + file.name)
const task = storageRef.put(file)
task.on('state_changed',
function progress (snapshot) {
self.status = 'UPLOADING...'
self.percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
},
function error () {
self.status = 'FAILED TRY AGAIN!'
self.isUploading = false
},
function complete (event) {
self.status = 'UPLOAD COMPLETED'
self.isUploading = false
storageRef.getDownloadURL().then((url) => { console.log(url) })
}
)
}
In 2019, I gained access to the url of a newly-saved file in firebase with the following function:
const uploadImage = async(uri) => {
const response = await fetch(uri);
const blob = await response.blob();
// child arg specifies the name of the image in firebase
const ref = firebase.storage().ref().child(guid());
ref.put(blob).then(snapshot => {
snapshot.ref.getDownloadURL().then(url => {
console.log(' * new url', url)
})
})
}
As of web version v9 (modular) you can achieve this in this way:
import { getStorage, ref, uploadBytes, getDownloadURL } from "firebase/storage";
uploadImage = () => {
const storage = getStorage()
const reference = ref(storage, 'file_name.jpg')
const file = e.target.files[0]
uploadBytes(reference, file)
.then(snapshot => {
return getDownloadURL(snapshot.ref)
})
.then(downloadURL => {
console.log('Download URL', downloadURL)
})
}