Is there a way to get all the URLs of the files located in a specific firebase storage library?
Currently using the following method:
List<String> URLs = [];
final ListResult _files = await _fireStorage.ref('groups/').list();
for (var element in _files.items) {
String addable = await element.getDownloadURL();
URLs.add(addable);
}
MY problem is that I have lots of files located in the groups folder and this async call takes like a ton of time to fetch for all individual elements. Is there any API call to get the links in bulk? Or should I just store the links in a firebase document and fetch them from there?
Thanks in advance!
In order to successfully return the downloadURL the client has to ping the storage bucket. Firebase then has to check the security rules to ensure that the operation is allowed, then verify that the object exists, and then return it's download URL to you. Unfortunately there is currently no way of doing this process in bulk.
It's quite common to store the downloadURL in a Firestore document so you can avoid the additional overhead and retrieve the downloadURL directly. But remember, downloadURLs are public and do not adhere to security rules. So make sure the document you're storing them in has proper rules placed on it.
Remember to perform a clean up operation and remove the reference in Firestore if you every delete the file.
Related
I want to delete the collection with many documents and subcategories in it. How can I do it?
The code below didn't work. I tried many methods. I want to delete all information and subcollections in the collection.
AllDelete() async {
user = await _auth.currentUser();
final userRef = Firestore.instance.collection('users').document(user.uid).collection("SORU");
userRef.getDocuments().then((snapshot) {
snapshot.documents.forEach((doc) {
doc.data.remove(1);
print("IDLERRRR ${doc.documentID}");
});
});`
The code didn't work means, how did you check ?
I suspect some of the collections got deleted some weren't.
Note that delete is NOT an atomic operation in a document based NoSQL database like firebase and it's possible that it
may fail after only deleting some documents.
If you want anyway to try, you can manually handle all the delete requests of different documents recursively using a cloud function shown here
But it is highly not recommended to do it from a web client, like Flutter.
From the docs
Deleting a collection requires coordinating an unbounded number of
individual delete requests. If you need to delete entire collections,
do so only from a trusted server environment. While it is possible to
delete a collection from a mobile/web client, doing so has negative
security and performance implications.
Cheers :)
I am trying to get the download urls from 300 files inside the firebase storage :
items.forEach((element) {
setUrls(element.id);
});
void setUrls(String id) async {
String imageurl = await storageRef.child('id').getDownloadURL();
saveUrl(imageurl, id);
}
but it takes a lot of time to get all the files urls, how can i speed it up ?
Tried to call method to excute all 300 files at the same time, but still very slow, it gets one file at a time.
You could use the .listAll() method which buffers results in memory. You can even do this recursively if you need to go additional layers. Then call forEach like you did. Honestly not sure what kind of time this would save but it might help.
I would create a separate Firestore collection which stores just the id and URL of each image. Be sure to call getDownloadURL and save the result when images are added or changed. Then create a custom index to increase read speed. Just query that collection and loop the results.
To reduce the number of reads it is a general technique to maintain timestamp of last edits in documents and comparing timestamp to load only modified documents.
Here is an example from firebase docs:
db.collection('groups')
.where('participants', 'array-contains', 'user123')
.where('lastUpdated', '>', lastFetchTimestamp)
.orderBy('lastUpdated', 'desc')
.limit(25)
They claim this would reduce the reads.
I tried implementing the use-case, I have a document as shown below:
I have sections in my app where I use scorecards to list top scorers, My query is as follows
private void loadFriendScores(UserScorecard scorecard) {
Query friendScoreQuery=scorecardRef.whereIn("uid", scorecard.getFriendsList())
.whereGreaterThan("lastActive", scorecard.getLastActive()).limit(5);
FirestoreRecyclerOptions<UserScorecard> friends = new FirestoreRecyclerOptions
.Builder<UserScorecard>()
.setQuery(friendScoreQuery, UserScorecard.class)
.setLifecycleOwner(getViewLifecycleOwner())
.build();
TopScoresAdapter friendsAdapter = new TopScoresAdapter(friends, getContext(), this);
binding.topScorersFriendsRcv.setAdapter(friendsAdapter);
binding.topScorersFriendsRcv.setLayoutManager(new LinearLayoutManager(getContext()));
}
I assumed the query to load all modified changes along with others (from cache):
The screen on android is as follows:
While I expected it to load all of my friendlist (as I understood from docs).
I suppose they did not mention that we need to fetch the cached list, there is a way to do a cached request in firestore.
but I'm not sure if this is reliable perhaps the cache will be cleaned and the last request would be empty ,
then, you should save the last response using the localstorage library
#react-native-async-storage/async-storage
I'm struggling myself with the costs issue. The reads are way higher then 50 reads and I'm not sure how to count them properly. so I upvoted the issue
I want to store documents that I download from firestore. Each document has a unique id so I was thinking of a way I can store that document in json format or in database table (so I can access its fields) and if that id is not present in the memory than just simply download it from firestore and save it. I also want these documents to be deleted if they are not used/called for a long time. I found this cache manager but was unable to understand how to use it.
you can download the content by using any of the flutter downloadmanager and keep the path of the downloaded content in sqllite and load the data from local storage rather than url if the data is already saved.
Following pseudo-code may help you:
if(isDownloaded(id)){
//show from local;
} else {
// show from remote
}
you can manually check whether the resources are being used or not by keeping a timestam of it and update the timestamp only when it is shown. and you can run a service which looks for the unused resources and delete it from storage and the databse too.
I need to query my Cloud Firestore database periodically for maintenance. I'm new to REST and I've spent way too long trying to solve this myself, so I figured I could use some advice.
My Firestore is set up like so:
users > {uid} > uploaded-files > {file-hash}
{file-hash} is a document that contains several fields such as filename, source, and size
All I'm trying to do is get a list of every single filename from every single uploaded-file, including from multiple {uid}'s.
I've managed to send a successful request and get a single filename using the firestore.projects.databases.documents.get method using the API explorer, but I can't seem to get any other methods to work, namely firestore.projects.databases.documents.list
This is the successful request using firestore.projects.databases.documents.get:
GET https://firestore.googleapis.com/v1beta1/projects/{project-id}/databases/(default)/documents/users/7eGfdgGfaG0HSXdfmxMN2/uploaded-files/WGtcJBX9fdGdhdtjB?mask.fieldPaths=filename&key={YOUR_API_KEY}
Part of my issue is that I can't figure out how to get requests to work without hard-linking document names - in other words, I don't know how to to replace {uid}, or any other collection, with a wild-card so that the request returns documents from all uid's.
Really any help is greatly appreciated.
The Use the Cloud Firestore REST API documentation has instructions on getting started. The Firestore REST API documentation shows how to fetch documents.
In your case you would need to list the user-uid documents then go after the uploaded-files for each one, or iterate over the results of the list.