-1

I want to get a Document from Firestore, but just with some fields of the doc.

I found 2 use cases for this. One of these is:

Users in Firestore

UsersCollection
     UserDocument
           email
           uid
           photoUrl
           name

If I want to make a chat with all of the users in the users collection, I need to get all the docs in the user collection. But these docs contain some important info that's not useful to our chat, like the e-mail. Can't I just request from firebase the user document without the e-mail field? Can't a hacker find the user document in memory and get their e-mail? The e-mail is not useful for the chat, I only need the name, uid and photoUrl, the e-mail is no use for this feature, but I still get it with the whole document. How do I "except" or get the document without the e-mail? This is more about security and user privacy.

Another use case for this would be a like system. Let's say we have a post structured like this in firebase:

    PostsCollection
        PostDocument
            number of likes
            arrayOfUsersThatLiked
            photoUrl

number of likes is incremented by a cloud function that when arrayOfUsersThatLiked is modified, the function adds the length of the array in the number of likes field. (arrayOfUsersThatLiked is used to not let the user like more than 1 time, so if someone liked the post, arrayOfUsersThatLiked will keep track of who and will not let them like again)

When we get the post document from the db, we will actually get that usersThatLiked array with a lot of uids along with the things that we need, we only need the photoUrl and the number of likes on the post, not the usersThatLiked array. (it would be a pain also to store such a huge string array).

So the main question remains, how do I only get the document with only the fields that I want to? It's a matter of privacy/security and performance.

Alexandru Stroescu
  • 1,067
  • 1
  • 9
  • 16

1 Answers1

1

With the Client SDKs (including the FlutterFire plugin) it is not possible to get only a subset of the fields for a Document. When you fetch a Document you get it with all its fields.

Here are three possible approaches:

  1. Dernomalize your data: You create another collection which contains documents that only have the fields you want to display in the front end. The complexity is that you need to keep the two collections in sync: when you create/modify/delete a doc in the master collection, you need to update the other collection. This can be done from your front-end (e.g. you write to the two collections in a batched write) or with a Cloud Function, triggered in the back-end with an onWrite trigger. In terms of security, you open read access only to the second collection, not to the master one.

  2. Use the Firestore REST API: With the REST API you can use a DocumentMask when fetching documents, which will "restrict a get operation on a document to a subset of its fields. ". Note, however, that a "hacker" could get the collection ID and fetch the documents without the Mask.

  3. Use a Cloud Function to access the Firestore documents. With a Cloud Function, you have full control on what you want to send back to the front-end, since you query the collection from within the Cloud Function and build the response in the Cloud Function. However, using a Cloud Function instead of a Client SDK has several drawbacks: see this article for more details.

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121