I'm currently creating a file upload and display feature for a web app.
I need to add a custom property (e.g accountID) so that I can later display only the images belonging to a specific account.
I'm using cfs:standard-packages with gridfs to upload/store my images.
I believe I need to add a beforeWrite function to the FS.Store but am unsure how to go about it.
The easiest way to do this is to immediately update the inserted object as follows:
var fileId = MyFiles.insert(file);
MyFiles.update({ _id: fileId },{ $set: { accountId: myAccountId }});
Note that the actual upload of the file object to the store will be asynchronous but you'll get the _id back synchronously and immediately.
Related
I have a bulk amount of data in CSV format. I am able to upload that data with python by converting them to the dictionary (dict) with loop. the whole data is getting uploaded.
but now I want to upload bulk data to firebase and images to storage and I want to link between each document and image because i am working on e-commerce react app. so that I can retrieve documents along with images.
which is a good way to do this? should I do this with javascript or python?
I uploaded data manually to firebase by importing from there but again I am unable to upload bulk images to storage and also unable to create references between them. please give me a source where I can find this solution
This is tough, because it's hard to fully understand how exactly your images and CSV's are linked, but generally if you need to link something to items stored in Firebase, you can get a link either manually (go into storage, click and item, and the 'Name' Field on the right hand side is a link), or you can get it when you upload it. So for example, I have my images stored in firebase, and a postgres database with a table storing the locations. In my API (Express), when I post the image to blob storage, I create the URL of the item, and post that as an entry in my table, as well as setting it to be the blobs name. I'll put the code here, but obviously it's a completely different architecture to your problem, so i'll try and highlight the important bits (it's also JS, not Python, sorry!):
const uploadFile = async () => {
var filename = "" + v4.v4() + ".png"; //uses the uuid library to create a unique value
const options = {
destination: filename,
resumable: true,
validation: "crc32c",
metadata: {
metadata: {
firebaseStorageDownloadTokens: v4.v4(),
},
},
};
storage
.bucket(bucketName)
.upload(localFilename, options, function (err, file) {});
pg.connect(connectionString, function (err, client, done) {
client.query(
`INSERT INTO table (image_location) VALUES ('${filename}')`, //inserts the filename we set earlier into the postgres table
function (err, result) {
done();
if (err) return console.error(err);
console.log(result.rows.length);
}
);
});
console.log(`${filename} uploaded to ${bucketName}.`);
};
Once you have a reference between the two like this, you can just get the one in the table first, then use that to pull in the other one using the location you have stored.
I have a NestJS project with a typeORM driver (MySQL). When a user uploads a photo then the server saves file in public directory and saves a relative path in DB: /public/user22.png
When a user sends a request for getting info about their profile, the server should return an absolute path.
Also a user can get a list of users.
I can edit the returning object for the user profile. But i don't want to use cycle for editing the list of users. Are there any optimal algorithms to solve the issue?
You have two solutions to transform your relative path to an absolute path.
First option is to append every image used in your front-end based on an environment variable called apiBaseUrl for example.
const users = await axios.get('/users');
<img src={`${process.env.NEXT_PUBLIC_API_BASEURL}/${users.image}`}/>
It will start to be unoptimized if you'r using this many times of course.
Second option is to create modify before returning your result to modify your photo value with an environment variable called baseUrl for example.
const result: exampleEntity = this.exampleRepository.find();
const newExample: exampleEntity = this.exampleRepository.create({
...result,
photo: this.configService.baseUrl + result.photo,
});
return entityExample;
If you don't handle environment variables for the moment, you can read the configuration documentation
I am trying to get a form upload working to upload data to my Firestore db as well as upload an image to my firebase storage.
Individually I can do both, however outside of storing the exact URL of the uploaded image I can't seem to figure out how to programatically store the Reference to the image in my firestore.
In the console I can set the type to "Reference"
But whatever I try programatically doesn't work:
Post image upload:
const url = await storageRef.snapshot.ref.getDownloadURL()
let imageRef = storage.ref().child(`test/${this.imageData.filename}`).ref
// let imageRef = storageRef.snapshot.ref
// let imageRef = storage.ref(`test/${this.imageData.name}`)
const docRef = await testImagesCollection.add({
thumbnail: imageRef,
dateCreated: firestore.FieldValue.serverTimestamp()
})
alert("upload succeeded", docRef.id)
I usually end up with: FirebaseError: Function DocumentReference.set() called with invalid data. Unsupported field value: a custom Reference object (found in field thumbnail)
If I have to I'll just store the URL but I rather not do that, if the console allows me to set a reference I should be able to do it programatically as well?!
Firestore reference types only work with references to other documents represented as DocumentReference objects. They don't work with references to objects in Cloud Storage. If you want to store a reference to an object in Cloud Storage, you should either store the path to the file in the bucket (as a string, not as a Reference object), or a download URL (whichever is more convenient for you).
If you have a Reference object, you can get a string path to it with its fullPath property.
Currently I am able to fetch a specific picture knowing its title and location in the storage, but I want to be able to show all pictures in one folder inside my storage knowing the location of that storage folder but not the content titles.
I have tried using the below code (projectID is the folder which I need to show all the elements of) but it doesn't seem to work. I am new to javascript so I apologize for the wrong function call of .once.
const childRef = storageRefer.child(`${projectID}`);
childRef.once("value", function(snapshot) {
snapshot.forEach(function(child) {
child.getDownloadURL().then(function(url) {
console.log(url);
});
});
});
this code should be able to log the url of all the images but all I get is an error about the .once function. If anyone knows what I am doing wrong or a better method in getting all the images in one folder inside my storage that would be super helpful, thanks!
Edit:
Looking back at this I realized I could store the location of the images into a database for them as I can easily iterate through a database without knowing what is inside and call to storage to get the image, but that seems sloppy?
There currently is no API call in Firebase Storage to list all files in a folder. If you need such functionality, you should store the metadata of the files (such as the download URLs) in a place where you can list them. The Firebase Firestore is perfect for this and allows you to also easily share the URLs with others.
var listRef = firebase.storage().ref().child('profiles/');
listRef.listAll().then(function(res){
res.items.forEach(function(itemRef){
itemRef.getDownloadURL().then(function (link) {
console.log(link);
})
})
})
}
This function brings all photos saved in the storage "Profile"
I hope it works for you.
#Shodmoth Check out this new firebase link (https://firebase.google.com/docs/storage/web/list-files) for how to list all the files in a folder.
// Create a reference under which you want to list
var listRef = storageRef.child('files/uid');
// Find all the prefixes and items.
listRef.listAll().then(function(res) {
res.prefixes.forEach(function(folderRef) {
console.log(folderRef)
});
res.items.forEach(function(itemRef) {
console.log(itemRef) //can call .getDownloadURL() on each itemRef
});
}).catch(function(error) {
// Uh-oh, an error occurred!
});
I use lowDB dependency to control the JSON Data with Express and actually it works. But there is a bug and I cannot find how to solve it.
I create /create page to add information in JSON file and it contains 4 form and submit button.
And In express I code like this. each forms data will save it in variable and push with lowdb module.
router.post('/post', function (req, res) {
let pjName = req.body.projectName;
let pjURL = req.body.projectURL;
let pjtExplanation = req.body.projectExplanation;
let pjImgURL = req.body.projectImgURL;
console.log(pjName);
db.get('project').push({
name: pjName,
url: pjURL,
explanation: pjtExplanation,
imgurl: pjImgURL
}).write();
console.log(db.get('project'));
console.log(db.get('project').value());
res.redirect('/');
})
And it works well. But when I modify the JSON file myself (ex. reset the JSON file) and execute again. It shows the data that I reset before. I think in this app somewhere saves the all data and show save it in array again.
And When I shutdown the app in CMD and execute again, the Array is initialized.
As you may already know the lowdb persist the data into your secondary memory (hdd), and may return a promise depending on your environment when you call write method.As mentioned in the doc
Persists database using adapter.write (depending on the adapter, may return a promise).
So the data may be still getting write when you read them, so the old data is queried. Try this,
db.get('project').push({
name: pjName,
url: pjURL,
explanation: pjtExplanation,
imgurl: pjImgURL
}).write().then(() => {
console.log(db.get('project'));
console.log(db.get('project').value());
});