Get certain fields in document firestore flutter

963

With the Client SDKs and the Flutter plugin it is not possible to get only a subset of the fields of a Document. When you fetch a Document you get it with all its fields.

If you want to get only a subset of the fields of a document, you can implements the two following approaches:

  1. Denormalize your data: You create another collection which contains documents that only contain the fields you want to expose. You need to synchronize the two collections (the Users collection, which is the "master", and the new collection): for that it's quite common to use a Cloud Function. Note also that it's a good idea to use the same documentID for the linked documents in the two collections.
  2. Use the Firestore REST API to fetch the data: With the REST API you can use a DocumentMask when you fetch one document with the get method or a Projection when you query a Collection. The DocumentMask or the Projection will "restrict a get operation on a document to a subset of its fields". You can use the http package for calling the API from your Flutter app.

HOWEVER, the second approach is not valid if you want to protect the other users data: a malicious user could call the Firestore REST API with the same request but without a DocumentMask or a Projection. In other words, this approach is interesting if you just want to minimize the network traffic, not if you want to keep secret certain fields of a document.

So, for your specific use case, you need to go for the first solution.

Share:
963
Maxime Boissout
Author by

Maxime Boissout

Updated on January 03, 2023

Comments

  • Maxime Boissout
    Maxime Boissout over 1 year

    I'm currently working on an application where users can create groups and invite others in it. I would like people in the same group to be able to see their first and last names. To do that, I have a collection named Users where each of the users have a document contains all their personnal data, like first and last names, phone, position , ... I have also another collection named Groups, where all of my groups are stored, with their name, and an array contaning the ID of the members.

    When an user open the app, a first request is done for request his groups (he recieve the groups names and the arrays of members). After, if he want to know the user in a certain group, another request is done for search only the first and last name of all the members.

    So, I imagine that there is a query that will return me only the fields that I would like to retrieve, and that there is a rule allowing a potential hacker to be refused access to the entire user document except if the user is the owner of the document.

    // For retrieving my user's groups
    Stream<List<Group>?> get organizations {
      return firestore
        .collection('Groups')
        .where('members', arrayContains: this.uid)
        .snapshots()
        .map(_groupsFromSnapshot);
    }
    
    // For retrieving names of the members of a group
    Stream<List<Member>?> getMembers(Group group){
      return firestore
        .collection('Users')
        // and i dont know what to do here ...
    }