How to fetch documents from a collection without certain fields from Firestore? [duplicate] - firebase

This question already has answers here:
Is there a way to select only certain fields from Firestore?
(1 answer)
How to access a specific field from Cloud FireStore Firebase in Swift
(5 answers)
How to access some fields of firestore in flutter? [duplicate]
(1 answer)
How to get value of some field in firebase firestore android?
(4 answers)
Closed 2 months ago.
I have a collection let's say "files" and a "file" document has 2 main properties (field) : name and content.
(note: I know storing files in a Firestore is not a good idea but that's just an example, let's assume the files are just text files)
When my app opens I want to be able to fetch all user's file names but not the content :
files = [{name: 'a'}, {name: 'b'}, {name: 'c'}, ...]
The reason is obvious I don't want to pull files' content unless the user explicitly ask for from the UI, minimizing the size of data being pulled from Google Cloud and reducing the cost over time.
But collection(db, 'users', user.uid, 'files') seems to return all docs data. Even worst! if one "file" document change, all the docs and their content are being pulled again from the UI onSnapshot listener...
Reading the TypeScript doc I don't see an option to do atomic selection on docs' fields. Am I missing something?

Related

How to update a particular field in all the documents of a collection in cloud firestore? [duplicate]

This question already has answers here:
How to update a single field of all documents in firestore using flutter?
(3 answers)
Can Firestore update multiple documents matching a condition, using one query?
(8 answers)
Closed 12 months ago.
I am developing a Quiz App using flutter, firebase and cloud firestore in which users can play a quiz only once per day and the total score of all users will be reset to zero after every month. I am trying to achieve this by creating these two fields in each user document in the users collection:
isReadyToPlay: This field stores a boolean value 'true' if user didn't play the quiz, and changes to 'false' when user completes the quiz. I display a "start quiz" button if the value is true and remove it if the value is false. But I need to update this value to 'true' again, to allow the user to play the quiz the next day. So how do I update this field in all the documents from the collection?
total_score: This field stores the total score of all the quizzes a user plays. I want to reset this score to zero after every month. So again, I need to update this field in all the documents of the users collection.
I want to update the mentioned fields in all the documents at once from the admin end. If this is not possible, what could be a work around to achieve this?
You can do it like this first get all the documents as a snapshot and just update the required field of each document in the snapshot.
FirebaseFirestore.instance.collection('users').get().then((snapshot) {
for (DocumentSnapshot ds in snapshot.docs) {
ds.reference.update({
'isReadyToPlay': true, //True or false
'totalScore': 254 //Your new value
});
}
})

FireStore - How to not allow creation of document if there is another document with the same value in a field [duplicate]

This question already has answers here:
Firestore unique index or unique constraint?
(5 answers)
Enforcing unique userIds in Firebase Firestore
(1 answer)
firebase rule for unique property in firestore
(2 answers)
Closed 2 years ago.
I have a Firestore document collection called registrations. Inside registrations, there are documents that contain name, phone number, and age of persons. I want to write the security rules database which allows the creation of person document if and only if another person with the same name does not exist on the database
Thanks in advance
It sounds like you want to keep your names distinct, such as with a UNIQUE constraint in SQL.
It is not possible to query specific document fields in Firestore security rules.
There are two ways to do what you want with Firestore:
use name as your document id
or create a collection /usedNames with name as document id, so that in your security rule you can test:
let name = request.resource.data.name;
return exists(/usedNames/$(name)) == false

Firestore Document Rules on Field [duplicate]

This question already has answers here:
Firestore Security Rules - How can I check that a field is/isn't being modified?
(10 answers)
Closed 3 years ago.
I am looking to apply firestore rules to restrict the change (write, update) of a specific field in a document.
From what I understand in the docs you cannot apply rules on read: to document fields as documents need to be read in their entirety, however, it's not stated about writes, updates?
My structure is like the below example;
match /ads/{adDocument} {
//adDocument has a field "price" this needs to only be read not changed/updated.
};
How would I go about implementing this?
You can write a CQRS mediator for all changes, and disallow all write to the documents.
To make a change, the client can add a document to mutate the document on all mutable fields:
/PATCH_ads/{adDocument}:
- itemName: "newItemName"
The mediator should be triggered once a document is added in the PATCH_ads collection. The mediator should reject the change if receiving a command to modify price field, and commit the change if the content of the requested change is valid.

Fetch documents from multiple subcollections - Firebase [duplicate]

This question already has answers here:
Firestore query subcollections
(11 answers)
Closed 3 years ago.
I'm creating a web app for admin with firebase integration, this web app is used by admin to monitor posts or comments posted by user from Android or iOS app developed in ionic.
I'm using Firebase firestore, and following is the database design
posts/{postsDocument}/comments/{commentsDocument}.
The comments here is sub-collection for postsDocument that holds all the comments for a particular post. Also postDocument and commentsDocument contains Firebase uid of the user.
My problem is, whether it's possible to fetch all the comments commented by a particular user. I can query a single collection, but in this scenario commentsDocument is a subcollection and i want to fetch all comments across all the post by a user for monitoring purpose.
You can check firebase collection group query
var commentsQuery = db.collectionGroup('comments').where('commentOwnerID', '==', userId);//userId - firebase id of the user who commented
commentsQuery.get().then(function (querySnapshot) {
querySnapshot.forEach(function (doc) {
console.log(doc.id, ' => ', doc.data());
});
});
Also you might have to create index that supports your query, check console for the the link for creating index

How to query by item existance in array on Firestore? [duplicate]

This question already has answers here:
Firestore: Query by item in array of document
(5 answers)
Closed 4 years ago.
I have read this https://firebase.google.com/docs/firestore/solutions/arrays but I still couldn't figure out how it solves the issue of querying not-hardcoded user-generated items in array.
Let's say I have a Party collection:
Party {
name: "Birthday party",
invitees: [56448, 869987, 230232, 202030] # user id's of invited people
}
How can I query only parties where I'm in the invitees array without making an index for each possible ID?
https://firebase.google.com/docs/firestore/solutions/arrays
Limitations
The solution shown above is a great way to simulate array-like structures in Cloud Firestore, but you should be aware of the following limitations:
Indexing limits - A single document can have only 20,000 properties in order to use Cloud Firestore built-in indexes. If your array-like data structure grows to tens of thousands of members, you may run into this limit.
So the short answer is no.
If I were using Firebase Database, I would create a cloud function to watch the party/invitees branch on creation and modification, then propagate the invitation to a branch on the userID profile. Because you can be invited and uninvited, the changeset contains old and new and you can remove invitations from people who are in the previous but not in the next.
I haven't explored Cloud Functions for Firestore (yet) but I suspect that you can do something similar.
If you follow the method described in the documentation you point to (i.e. https://firebase.google.com/docs/firestore/solutions/arrays) and instead of storing the users in an array you save an object like
Party {
name: "Birthday party",
invitees: {
"56448": true,
"869987": true,
"230232": true,
.....
}
}
you will be able to query like
var yourUserID = .....; //e.g. '869987'
db.collection('invitees')
.where('invitees.' + yourUserID, '==', true)
.get()
.then(() => {
// ...
});
And as the doc says "This technique relies on the fact that Cloud Firestore creates built-in indexes for all document fields, even fields in a nested map.", so no worries for maintaining the indexes.

Resources