Retrieving all the data from firebase excluding some fields

Viewed 1759

I am working on a project using angular,firebase and cloud functions.I have data as follows:

data image

I want to retrieve all the data excluding profile_picture field.In cloud function:

    exports.getPartner = functions.https.onRequest((req, res) => {
    res.header('Content-Type', 'application/json');
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Content-Type');


    if (req.method === 'OPTIONS') {
        res.status(204).send('');
    }


    var partner = admin.database().ref().child('partner');
    partner.on("value", function (snapshot) {
        res.status(200).json({ partner: snapshot.val() });
    }, function (errorObject) {
        console.log("The read failed: " + errorObject.code);
    });
});

Is there any way in cloud function/in angular to exclude some field so that data fetching will be faster? Any help is appreciated.

2 Answers

While fetching data from firebase real time database (i.e from particular node) you will download entire data at the location including the child collection if you have. See firebase doc for listening values

There are two ways you can avoid the profile_picture

  1. While returning the response to the https calls you can eliminate the profile picture key.
  2. Otherwise put the profile picture in some other tree, if you don't want it while you download the partner tree.

Let me explain in detail below

Step 1 : Eliminating the Profile Picture from the object

var partner = admin.database().ref().child('partner');
partner.on("value", function (snapshot) {
    res.status(200).json({ partner: snapshot.val() }); 
    // don't simply return like this. Instead follow like below
   var partners = [] ; // create a partners array
  snapshot.forEach(function(childSnap){
      var p = childSnap.val();
      p.id = childSnap.key // this will the id of the each child inside the partner tree
      delete p.profilePicture;
      partners.push(p); // 
  });
  res.status(200).json({ partner: partners }); 
}, function (errorObject) {
    console.log("The read failed: " + errorObject.code);
});

If you do like below you can eliminate the profile picture key from the https response. But keep one thing mind, anyway you'll download all data from the tree.

Step 2: Putting profile picture in some other tree

To do this, you need to change the method which adds the data to the partners tree. Let me explain this.

For Example : While adding the partners data put the profile_picture in some other like partnerDetails tree.

var partnerKey = firebase.database().ref('partner').push().key;
var partnerUpdate = {};
partnerUpdate['partner/' + partnerKey] = partner; // parnter Object without profilepicture
partnerUpdate['partnerDetails/' + partnerKey + 'profilePicture'] = profilePicture; 
// the partnerKey must be same for the both the tree because it's the associated key for both of them. 

firebase.database().ref().update(partnerUpdate) // this is called multipath update

So after doing like this you wont have the profile picture in the partner tree. I hope you list the partners tree in the client and click one of the partner from the list which will display the entire details. If you doing so, you can pass the partners key (i.e.associated key) and get the partners profile picture to do so,

firebase.database().ref('/partnerDetails/' + partnerId).on('value').then(function(partDetailSnap){
  // here you will get the profile_picture of the partner. 
});

Cloud Functions will be really fast. Unless it needs cold start. You can do same for the some other fields like i did it for the profile picture using step 2 or 1.

Hope this gives some idea. Feel free to ask more.

I make the assumption that the partner node is the parent node of the nodes you show in your picture (-L80_3..., -L84i...).

In your function you are listening to the entire partner node, so what you are going to receive with snapshot is the full JSON tree under the partner node. There is no way to only receive a subset of this JSON tree.

If you want to avoid receiving the profile_picture field, one way is to create another node where you store this piece of data as shown below. Then, when you query the partner node you get only the info you need.

+ partner
    + -L80_3......
       + partnerEmail   //No more profile_picture node here
       ......
       + uid
    + -L84i.......
       + partnerEmail
       ......
       + uid
+ profile_pictures
    + -L80_3......   //same id than the "parent" partner node
       + profile_picture
    + -L84i.......
       + profile_picture

Finally, note that by using the on() method, you are "listening for data changes at a particular location. Your callback will be triggered for the initial data and again whenever the data changes.". It makes more sense to use the once() method in a Cloud Function, since you only want to read the data once.

Related